Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS: Introduce API for making screen reader announcements #14168

Closed

Conversation

rigdern
Copy link
Contributor

@rigdern rigdern commented May 25, 2017

This change introduces some APIs that are useful for making announcements through the screen reader on iOS:

  • announceForAccessibility: The screen reader announces the string that is passed in.
  • announcementFinished: An event that fires when the screen reader has finished making an announcement.

You can already solve similar problems with RN Android using the accessibilityLiveRegion prop. Live regions are a different feature but they can be used to solve the same problem. This commit does not attempt to add live region support in RN iOS because Apple did not build live region support into iOS.

Test Plan (required)

Verified that announceForAccessibility causes VoiceOver to announce the string when VoiceOver is enabled. Verified that announcementFinished fires with the appropriate data in the event object. Additionally, my team has been using this change in our app.

Adam Comella
Microsoft Corp.

@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. GH Review: review-needed labels May 25, 2017
VOICE_OVER_EVENT,
handler
);
var listener;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-trailing-spaces: Trailing spaces not allowed.

handler
);
}

_subscriptions.set(handler, listener);
return {
remove: AccessibilityInfo.removeEventListener.bind(null, eventName, handler),
};
},

/**

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-trailing-spaces: Trailing spaces not allowed.

var listener = RCTDeviceEventEmitter.addListener(
VOICE_OVER_EVENT,
handler
);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no-trailing-spaces: Trailing spaces not allowed.

{
NSDictionary *userInfo = notification.userInfo;
// Response dictionary to populate the event with.
NSDictionary *response = @{@"announcement": userInfo[@"UIAccessibilityAnnouncementKeyStringValue"],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the variable names for this instead of the string (so userInfo[UIAccessibilityAnnouncementKeyStringValue]

@rigdern
Copy link
Contributor Author

rigdern commented May 25, 2017

@javache Thanks for reviewing. I addressed your comment.

@shergin shergin added the Platform: iOS iOS applications. label May 26, 2017
@facebook-github-bot facebook-github-bot added GH Review: accepted Import Started This pull request has been imported. This does not imply the PR has been approved. and removed GH Review: review-needed labels May 26, 2017
@facebook-github-bot
Copy link
Contributor

@javache has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

I tried to merge this pull request into the Facebook internal repo but some checks failed. To unblock yourself please check the following: Does this pull request pass all open source tests on GitHub? If not please fix those. Does the code still apply cleanly on top of GitHub master? If not can please rebase. In all other cases this means some internal test failed, for example a part of a fb app won't work with this pull request. I've added the Import Failed label to this pull request so it is easy for someone at fb to find the pull request and check what failed. If you don't see anyone comment in a few days feel free to comment mentioning one of the core contributors to the project so they get a notification.

@facebook-github-bot facebook-github-bot added Import Failed and removed Import Started This pull request has been imported. This does not imply the PR has been approved. labels May 26, 2017
Adam Comella added 3 commits May 26, 2017 17:49
This change introduces some APIs that are useful for making announcements through the screen reader on iOS:
  - `announceForAccessibility`: The screen reader announces the string that is passed in.
  - `announcementFinished`: An event that fires when the screen reader has finished making an announcement.

You can already solve similar problems with RN Android using the `accessibilityLiveRegion` prop. Live regions are a different feature but they can be used to solve the same problem. This commit does not attempt to add live region support in RN iOS because Apple did not build live region support into iOS.
@rigdern rigdern force-pushed the rigdern/announceForAccessibility branch from f877700 to e0900d4 Compare May 27, 2017 01:02
@rigdern
Copy link
Contributor Author

rigdern commented May 27, 2017

@javache Thanks for importing. It looks like the import failed due to merge conflicts. I fixed them.

@facebook-github-bot facebook-github-bot added the Import Started This pull request has been imported. This does not imply the PR has been approved. label May 30, 2017
@facebook-github-bot
Copy link
Contributor

@javache has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@rigdern rigdern deleted the rigdern/announceForAccessibility branch May 31, 2017 20:25
@shergin
Copy link
Contributor

shergin commented Jun 4, 2017

@rigdern That's awesome! Can we have it cross-platform? So, can we implement announceForAccessibility on Android using accessibilityLiveRegion? Should we?

@rigdern
Copy link
Contributor Author

rigdern commented Jun 6, 2017

@shergin Yes, we could add an Android implementation of announceForAccessibility. My team built something like that into ReactXP by putting a live region as a child of the root view and storing the announcement text in there: https://github.com/Microsoft/reactxp/blob/3f515aeffdd5ebb209c3a06d15ccbbbb4f60a1a3/src/native-common/RootView.tsx#L102-L106

I'm not sure if there's a way to implement the announcementFinished event though.

@"success": userInfo[UIAccessibilityAnnouncementKeyWasSuccessful]};

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is deprecated. We have to use typed event objects instead of strings.

@@ -101,6 +106,20 @@ - (void)didReceiveNewVoiceOverStatus:(__unused NSNotification *)notification
}
}

- (void)accessibilityAnnouncementDidFinish:(__unused NSNotification *)notification
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove __unused, please.

*/
announceForAccessibility: function(
announcement: string
): void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need : void here because it can be inferred.

@rigdern
Copy link
Contributor Author

rigdern commented Jun 7, 2017

@shergin The PR was already merged.

);
var listener;

if (eventName === 'change') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have to unify native event names with JS ones, this will drastically simplify this code fragment.

@shergin
Copy link
Contributor

shergin commented Jun 7, 2017

@rigdern Oh, I see. Anyways, we can improve this. 😄

@rigdern
Copy link
Contributor Author

rigdern commented Jun 7, 2017

@shergin They are good suggestions but I won't have time to submit another PR to address them.

For future reference, can you share an example of code that uses typed event objects instead of strings?

@shergin
Copy link
Contributor

shergin commented Jun 7, 2017

@rigdern Yes, sure, I will fix it myself.
See RCTEvent and RCTTouchEvent for reference.

@caocao-melon
Copy link

I am doing translation of this document. Can I interpret the 'announce' here as 'broadcast'?The meaning between the two words is different in Chinese. 'Announce' is more about expressing the meaning of the function declaration in coding,'Broadcast' is more about the screen reader. Which one is the right meaning?

@rigdern
Copy link
Contributor Author

rigdern commented Jul 20, 2018

@caocao-melon Am I correct in assuming you a referring to these snippets?

  /**
   * ...
   * - `announcementFinished`: iOS-only event. Fires when the screen reader has
   *   finished making an announcement. The argument to the event handler is a
   *   dictionary with these keys:
   *     - `announcement`: The string announced by the screen reader.
   *     - `success`: A boolean indicating whether the announcement was
   *       successfully made.
   * ...
   */

  /**
   * Post a string to be announced by the screen reader.
   * ...
   */

If so, it sounds like "broadcast" is what you want. All of these usages of "announce" have to do with the screen reader speaking some information to the user.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Import Started This pull request has been imported. This does not imply the PR has been approved. Platform: iOS iOS applications.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants