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

ASEditableTextNode contents not accessible to VoiceOver #1135

Closed
ay8s opened this issue Sep 19, 2018 · 8 comments
Closed

ASEditableTextNode contents not accessible to VoiceOver #1135

ay8s opened this issue Sep 19, 2018 · 8 comments
Labels

Comments

@ay8s
Copy link
Collaborator

ay8s commented Sep 19, 2018

Just had a report of this, it looks like the contents typed into an ASEditableTextNode aren't accessible when using VoiceOver. Will try and dig in tomorrow and see if I can do a pull request.

@ay8s ay8s added the bug label Sep 19, 2018
@maicki
Copy link
Contributor

maicki commented Sep 24, 2018

@ay8s Hey, did you find something out yet? Thanks!

@ay8s
Copy link
Collaborator Author

ay8s commented Sep 24, 2018

For now I ended up updating the accessibility value with the text from the textView in editableTextNodeDidUpdateText:

Also digging into a few other reports. Curious if Pinterest has any issues at all with ASEditableTextNode accessibility? Seems odd it's not free as a wrapper around UITextView.

@ay8s
Copy link
Collaborator Author

ay8s commented Oct 2, 2018

Digging into this one some more, there are pretty drastic differences in what VoiceOver reads between ASEditableTextNode and UITextView. In this example I simply put a ASEditableTextNode (green) at the top and a UITextView (red) below. Both are within a ASViewController with the UITextView wrapped in a ASDisplayNode.

No other settings were changed for either the ASEditableTextNode or the UITextView.

  • Doesn't say that it is a text field.
  • Doesn't say "Double tap to edit"
  • Doesn't say how to access misspelled words.

When inputting characters...

  • Doesn't read completed words.
  • Doesn't read insertion points.

Will continue to dig in, now sure if there may be something conflicting with the expected VO output.

Video: https://cl.ly/49c21c61cd58

@ay8s
Copy link
Collaborator Author

ay8s commented Oct 3, 2018

Digging in more to this today after exploring just using UITextView. Seems that if I use ASDK_ACCESSIBILITY_DISABLE it works correctly. Oddly ASViewController's that use ASEditableTextNode as the root node work fine, only when a ASEditableTextNode is included as a subnode default behavior is lost.

@ay8s
Copy link
Collaborator Author

ay8s commented Oct 3, 2018

@maicki @nguyenhuy So I think I've figured out the cause. When a ASEditableTextNode is a root node its textView is available via "view". This isn't the case when it is a subnode. When we're collecting the accessibility elements here we're not looking for the textView.

for (ASDisplayNode *subnode in node.subnodes) {
if (subnode.isAccessibilityElement) {
// An accessiblityElement can either be a UIView or a UIAccessibilityElement
if (subnode.isLayerBacked) {
// No view for layer backed nodes exist. It's necessary to create a UIAccessibilityElement that represents this node
UIAccessibilityElement *accessiblityElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:subnode containerNode:node];
[elements addObject:accessiblityElement];
} else {
// Accessiblity element is not layer backed just add the view as accessibility element
[elements addObject:subnode.view];
}
} else if (subnode.isLayerBacked) {
// Go down the hierarchy of the layer backed subnode and collect all of the UIAccessibilityElement
CollectUIAccessibilityElementsForNode(subnode, node, view, elements);
} else if ([subnode accessibilityElementCount] > 0) {
// UIView is itself a UIAccessibilityContainer just add it
[elements addObject:subnode.view];
}
}

I quickly hacked together adding the textView to the elements array and VoiceOver returned the correct information back to the user.

Any downsides you can see adding the following? I'm sure there may be a better more elegant solution.

  for (ASDisplayNode *subnode in node.subnodes) {
    if (subnode.isAccessibilityElement) {
      
      // An accessiblityElement can either be a UIView or a UIAccessibilityElement
      if (subnode.isLayerBacked) {
        // No view for layer backed nodes exist. It's necessary to create a UIAccessibilityElement that represents this node
        UIAccessibilityElement *accessiblityElement = [ASAccessibilityElement accessibilityElementWithContainer:view node:subnode containerNode:node];
        [elements addObject:accessiblityElement];
      } else {
        // Accessiblity element is not layer backed just add the view as accessibility element
        [elements addObject:subnode.view];
      }
    } else if (subnode.isLayerBacked) {
      // Go down the hierarchy of the layer backed subnode and collect all of the UIAccessibilityElement
      CollectUIAccessibilityElementsForNode(subnode, node, view, elements);
    } else if ([subnode accessibilityElementCount] > 0) {
      // UIView is itself a UIAccessibilityContainer just add it
      [elements addObject:subnode.view];
    } else if([subnode isKindOfClass:[ASEditableTextNode class]]){
      // UITextView is itself a UIAccessibilityElement just add it
      [elements addObject:((ASEditableTextNode *)subnode).textView];
    }
  }

@garrettmoon
Copy link
Member

Could we set isAccessibilityElement to YES on init in ASEditableTextNode? Then it would add subside.view which is the textView in this case?

@ay8s
Copy link
Collaborator Author

ay8s commented Oct 3, 2018

@garrettmoon When I try that VoiceOver simply reads "Actions available".

@ay8s
Copy link
Collaborator Author

ay8s commented Feb 2, 2019

Closing

@ay8s ay8s closed this as completed Feb 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants