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

setAccessibilityFocus not working on screen load #30097

Closed
Logan-Lim opened this issue Oct 2, 2020 · 9 comments · May be fixed by facebook/react-native-website#3438
Closed

setAccessibilityFocus not working on screen load #30097

Logan-Lim opened this issue Oct 2, 2020 · 9 comments · May be fixed by facebook/react-native-website#3438

Comments

@Logan-Lim
Copy link

Logan-Lim commented Oct 2, 2020

Description

There is an issue with setting accessibility focus on load of a screen. I was able to make it work by calling the function twice in a row.

React Native version:

System:
OS: Windows 10 10.0.19041
CPU: (16) x64 Intel(R) Core(TM) i9-9900KS CPU @ 4.00GHz
Memory: 14.18 GB / 31.93 GB
Binaries:
Node: 12.14.1 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.4 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
npm: 6.13.4 - C:\Program Files\nodejs\npm.CMD
Watchman: Not Found
SDKs:
Android SDK: Not Found
Windows SDK: Not Found
IDEs:
Android Studio: Version 4.0.0.0 AI-193.6911.18.40.6626763
Visual Studio: Not Found
Languages:
Java: 13.0.1
Python: 2.7.17
npmPackages:
@react-native-community/cli: Not Found
react: 16.13.1 => 16.13.1
react-native: https://github.com/expo/react-native/archive/sdk-39.0.0.tar.gz => 0.63.2
react-native-windows: Not Found
npmGlobalPackages:
react-native: Not Found

Steps To Reproduce

  1. Use a callback ref to get an element on screen load
  2. Get the element tag with findNodeHandle
  3. setAccessibilityFocus to the element tag

Expected Results

Accessibility focus should be moved to the desired ref. If I repeat step 3 twice, it will focus correctly, otherwise there is no focus set.

Snack, code example, screenshot, or link to a repository:

Issue raised on StackOverflow: https://stackoverflow.com/questions/63252638/setaccessibilityfocus-using-ref-not-working/
Broken version: https://snack.expo.io/@insats/example-accessibilityinfo-setaccessibilityfocus-not-working
Working version: https://snack.expo.io/@loganlim/example-accessibilityinfo-setaccessibilityfocus-not-working

@devinjameson
Copy link

I have the same issue. It works if I repeat step 3 twice.

@devinjameson
Copy link

I have the same issue. It works if I repeat step 3 twice.

Actually, to get it to work in all cases, I have to repeat step 3 three times.

@AdamGerthel
Copy link

Is it the same on Android as on iOS? IIRC it was only an issue on iOS for me, but I'm not entirely sure.

@yduman
Copy link

yduman commented Jun 14, 2021

It's the same on Android. I had to call the API four times until it set the focus appropriately. https://github.com/yduman/InclusiveShop/blob/main/src/components/ProductSizeSelect/ProductSizeSelect.tsx#L72 for reference.

@frags51
Copy link

frags51 commented Jun 24, 2021

On iOS, this sometimes leads to previous Text being announced, even if the state and text displayed inside my component has already changed. (calling setAccessibilityFocus in useEffect after updating state)

@tastafur
Copy link

tastafur commented Aug 13, 2021

I have a modal component that does not use the react native modal it is simply a react component and always the first time it does not work in Android in a useEffect and in turn wrapped in an InteractionManager.runAfterInteractions and in iOS it works perfect but in android it works for me perfect, when I focus on the title of the view to navigate to

@tastafur
Copy link

tastafur commented Aug 13, 2021

This my example
tag appears in the console log but then it doesn't focus, it's magic haha
with two calls to the focus method it works for me

  useEffect(() => {
    InteractionManager.runAfterInteractions(() => {
      if (titleRef && titleRef.current) {
        const tag = findNodeHandle(titleRef.current);
        console.log('tag', tag);
        if (tag) {
          setTimeout(() => {
            AccessibilityInfo.setAccessibilityFocus(tag);
          }, 300);
        }
      }
    });
  }, [titleRef]);
  
    useEffect(() => {
    InteractionManager.runAfterInteractions(() => {
      console.log('titleRef', titleRef.current);
      if (titleRef && titleRef.current) {
        const tag = findNodeHandle(titleRef.current);
        console.log('tag', tag);
        if (tag) {
          setTimeout(() => {
            AccessibilityInfo.setAccessibilityFocus(tag);
            if (Platform.OS === 'android') {
              AccessibilityInfo.setAccessibilityFocus(tag);
            }
          }, 300);
        }
      }
    });
  }, [titleRef]);

@YangShaoLong1984
Copy link

I also have the same issue.

@fabOnReact fabOnReact self-assigned this Oct 20, 2022
@fabOnReact
Copy link
Contributor

fabOnReact commented Oct 20, 2022

@fabOnReact fabOnReact removed their assignment Oct 20, 2022
fabOnReact added a commit to fabOnReact/react-native that referenced this issue Oct 24, 2022
changes discussed in
facebook#34969 (comment)
which consist in:

- Modal accepts prop TitleComponent which is a React.Element or
  Component and represents the title of the modal.
  The solution is taken from ListHeaderComponent in VirtList
- AccessibilityInfo.sendAccessibilityEvent is triggered to focus on the
  Title when the modal opens
- sendAccessibilityEvent needs to set a timeout of 1s (see facebook#30097 and https://stackoverflow.com/questions/28472985/android-set-talkback-accessibility-focus-to-a-specific-view)
- TitleComponent Styling and positioning is defined outside of reactnative
  This has to be reviewed as ListHeaderComponent uses
  ListHeaderComponentStyle

Notes:

"Improvements:
Trigger focus on components using Fabric API (findNodeHandle is deprecated, setAccessibilityFocus). setAccessibilityFocus has several issues (stackoverflow), and I can not set a ref on a modal.

componentDidMount seems to trigger before rendering the Modal children, the lifecycle does not work correctly with a modal on Fabric.

You need to use forwardRef to call sendAccessibilityEvent
Need to change the way you create the title component so that you create a forwardRef and then use this to send the accessibility event"	"https://reactnative.dev/docs/new-architecture-library-intro#preparing-your-javascript-codebase-for-the-new-react-native-renderer-fabric
https://reactnative.dev/docs/accessibilityinfo#setaccessibilityfocus
https://reactnative.dev/docs/new-architecture-library-intro#preparing-your-javascript-codebase-for-the-new-react-native-renderer-fabric"
"Test Text component solution without using getNativeRef, as the problem could be caused by timeout and not ref. Check the keys and try to use the _nativeRef
Implement getNativeRef for the Text component and use it in Modal to call setAccessibilityFocus"	https://github.com/fabriziobertoglio1987/react-native/blob/accbbfc01af57eda34374ce3b13e36b6e7c12a93/Libraries/Components/TextInput/TextInput.js#L1213
"Adding setTimeout with a wait of 1-second fixes issues with setAccessibilityFocus does not onLoad

The reason is triggered focus on other elements, so we need to use an API to wait for the focus to display on that element

Try to use runAfterInteraction"	"facebook#30097
https://reactnative.dev/docs/next/interactionmanager#runafterinteractions"
"Review meeting notes and Brett suggestion
Consider removing the sendAccessibilityEvent as violates WCAG 2.0 regulations, including 3.2.1 and 3.2.3"
Test Android
"-  The title component displays under the Modal on Android.
The title receives focus with the ModalPresentation example.
The title does not receive focus in the ModalOnShow example.
=> In both examples, the titles displays under the modal
=> In ModalOnShow, the title does not receive focus
Apply the same prop as in the ModalPresentation and see if the title receives focus
Remove style
Put the title directly in the ModalOnShow and trigger the focus
Trigger the focus manually with a button instead of using useEffect( _ref )
Trigger focus manually with a button in the Modal.js"
"setAccessibilityFocus correctly moves the focus when triggered with Button. The issue could be caused:
ref is undefined
read conversation facebook#30097
alternative callback to _showModal (onLoad)
TalkBack moves focus after calling sendAccessibilityEvent => increase timeout"	facebook#30097
"Test functionality on iOS:
test functionality on iOS with Xcode build"
"Improve solution and finalize diff before final commit:
Fix issue with sendAccessibilityEvent based on stackoverflow solution or runAfterIteraction (setAccessibilityFocus does not onLoad)
TitleComponent should move to rn-tester ModalPresentation and ModalOnShow
forwardRef may not work"	"https://github.com/fabriziobertoglio1987/react-native/blob/accbbfc01af57eda34374ce3b13e36b6e7c12a93/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/SurfaceMountingManager.java#L968
https://stackoverflow.com/questions/28472985/android-set-talkback-accessibility-focus-to-a-specific-view
facebook#30097"
fabOnReact added a commit to fabOnReact/react-native that referenced this issue Nov 18, 2022
iOS does not have issues with sendAccessibilityEvent (facebook#30097 (comment)), for this reason setTimeout is not required
test on iOS
https://www.icloud.com/iclouddrive/00cgfwQLkaoFQHvxh-Dj89zUA#ios_modal_title
OlimpiaZurek pushed a commit to OlimpiaZurek/react-native that referenced this issue May 22, 2023
…vent (facebook#34969)

Summary:
- Adds `AccessibilityEvent.TYPE_VIEW_HOVER_ENTER` to AccessibilityNodeInfo sendAccessibilityEvent
- Adds an example implementation.

fixes facebook#30860 fixes facebook#30097
Related Documentation facebook/react-native-website#3438

## Changelog

[Android] [Added] - Add TYPE_VIEW_HOVER_ENTER to AccessibilityNodeInfo sendAccessibilityEvent

Pull Request resolved: facebook#34969

Test Plan:
Android: facebook#34969 (comment) facebook#34969 (comment)
iOS: facebook#34969 (comment) facebook#34969 (comment)

Reviewed By: christophpurrer

Differential Revision: D42613990

Pulled By: lunaleaps

fbshipit-source-id: 8c8950610799dcc74067d2b47b44d4ff030f66e5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment