-
Notifications
You must be signed in to change notification settings - Fork 6k
Force the a11y focused node for a screen change notification on iOS. #14513
Conversation
use the route's name node as the focused node.
Is there some way we could test this? |
I don't think we have any system in place for automated testing of this on iOS, so I am not sure what we can do here. I have run this manually against several test apps and the gallery. I didn't see anything that seemed broken to me, but that is certainly not exhaustive. Do we have a better way to evaluate these kinds of changes? |
- (id)routeFocusObject { | ||
// Returns the first SemanticObject in this branch that has | ||
// the NamesRoute flag with a non-nil semantic label. Otherwise | ||
// returns nil. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it guaranteed that a node with kNamesRoute is always focusable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe so. In the isAccessibilityElement
method on SemanticsObject
it uses:
return (([self node].flags & ~flutter::kScrollableSemanticsFlags) != 0 &&
[self node].flags != static_cast<int32_t>(flutter::SemanticsFlags::kIsHidden)) ||
![self node].label.empty() || ![self node].value.empty() || ![self node].hint.empty() ||
([self node].actions & ~flutter::kScrollableSemanticsActions) != 0;
So any node with a label should be a11y focusable.
@vick08 pointed out in material-components/material-components-flutter-gallery#517 that the focus should always go to the first element on the screen. Maybe he can help with figuring if this is ok behavior. |
Sorry. What I said in the mentioned issue is that accessibility services should manage the focus according to their specific needs. We should simply provide the necessary signals. |
Closing in favor of #19826 |
Currently on iOS, when a screen change has occurred (a route change), we pass the most recent route scope's label as the parameter to the
UIAccessibilityScreenChangedNotification
. VoiceOver then picks a new node to move its a11y focus to. The way it does this is seems pretty random, depending on the structure of the SemanticObjects we present it, and doesn't give us a lot of control. However, the parameter toUIAccessibilityScreenChangedNotification
can also be theSemanticObject
that we want to have focus after the change.This PR makes use of this and passes the new route's label node as the focus for the screen change. This fixes a couple of issues: flutter/flutter#46625, and flutter/flutter#44001.
This seems like a good fix to me, but I am not that familiar with how our semantic tree deals with scopes. Can anyone see any issue with using the label node for focus instead of just announcing the label and letting VoiceOver pick the focus for us?