accessibility-code-examples icon indicating copy to clipboard operation
accessibility-code-examples copied to clipboard

iOS input-label guidance incorrectly states to hide the visible label text from VoiceOver focus

Open pauljadam opened this issue 2 years ago • 11 comments

The current iOS input-label guidance says to hide the visible label text of an input from VoiceOver focus which is abnormal behavior compared to forms on the web. Screen readers on the web and on all other platforms will normally read the label text first and then the input but the label is never hidden from screen reader focus.

https://github.com/appt-org/accessibility-code-examples/blob/main/input-label/ios.md

label.text = "Name"
**label.isAccessibilityElement = false**
field.accessibilityLabel = label.text

This guidance would be like saying to place aria-hidden=true on all

Also the Android guidance does NOT say to hide the label text from screen readers so there is no consistency in how this is recommended. There's also no guidance saying to hide the label for flutter, react, or xamarin.

If an iOS VoiceOver user has low vision and also runs screen magnification at the same time, they may see the label text and try to touch it to hear what it says but that would not be possible if you hide the label text from VoiceOver focus.

Another issue is the label hiding hack creates VoiceOver touch exploration "Dead Space" where when you move touch focus from one input to the other you hear the "ding ding ding" which indicates you can't focus on the label element so you can't as easily move your finger between each element on the page.

pauljadam avatar Nov 07 '23 19:11 pauljadam

Agreed. Upvote.

alexstine avatar Nov 07 '23 19:11 alexstine

Hi @pauljadam, thanks for raising this issue. This code sample was written by me. It's specifically about linking labels to input fields.

A shortcoming on iOS is that we don't have a way of linking labels to text fields. On the web we have <label for> and and Android we have labelFor. This is why the Android guidance doesn't include this workaround.

When using VoiceOver on iOS on a website with multiple <label for> and <input>, the focus moves from input field to input field when swiping right. The labels are skipped. However, the labels are focusable when you explore by touch.

Labels are not focusable when setting isAccessibilityElement to false on iOS. Therefore I do agree that labels on iOS should also remain focusable.

We still have to answer this question: what is the best work-around to programmatically associate a label on iOS with an input field?

Do we set the same accessibilityLabel twice, on both the label and the input field? For VoiceOver users this means they will hear the same label twice.

JJdeGroot avatar Nov 08 '23 09:11 JJdeGroot

For SwiftUI we have accessibilityLabeledPair but haven't used it myself yet. Relevant discussion: https://stackoverflow.com/questions/73545427/pairing-two-elements-for-accessibility-purposes-with-accessibilitylabeledpairr

Maybe we can also backport this to UIKit? But first need a working code sample for SwiftUI.

JJdeGroot avatar Nov 08 '23 14:11 JJdeGroot

I think that is a newer behavior on iOS where it sometimes skips over labels when swiping. It used to swipe through everything like a desktop screen reader always has when using arrow navigation. Labels should definitely be focusable on explore by touch! Thanks for taking my feedback!!

Since Apple has not given us a labelFor property we just have to manually set the .accessibilityLabel which is only one line of code.

SwiftUI example: Text("Username") .frame(maxWidth: .infinity, alignment: .leading) TextField("", text: $text) .textFieldStyle(.roundedBorder) .accessibilityLabel("Username")

It's only being set once, not twice. VoiceOver will hear it twice though as expected.

pauljadam avatar Nov 08 '23 17:11 pauljadam

For SwiftUI we have accessibilityLabeledPair but haven't used it myself yet. Relevant discussion: https://stackoverflow.com/questions/73545427/pairing-two-elements-for-accessibility-purposes-with-accessibilitylabeledpairr

Maybe we can also backport this to UIKit? But first need a working code sample for SwiftUI.

I don't think that code actually works, like how heading levels in iOS don't actually work either.

pauljadam avatar Nov 08 '23 17:11 pauljadam

I have updated the iOS code sample: https://github.com/appt-org/accessibility-code-examples/commit/96ac5d6c85553056fda5a81c9dc50b1deab69181?diff=split

The SwiftUI behavior is equal to the UIKit behavior. We are in touch with a SwiftUI developer who will likely contribute code samples in Q1 2024. Thanks for the sample. A swift-ui branch will be created in the near-future and we will add all samples in one go.

I will keep this issue open for a little longer while there is still discussion on LinkedIn.

JJdeGroot avatar Nov 09 '23 11:11 JJdeGroot

On iOS, there is no attribute to link a label to an input field. **We recommend combining** [UILabel](https://developer.apple.com/documentation/uikit/uilabel) with a [UITextField](https://developer.apple.com/documentation/uikit/uitextfield) or [UITextView](https://developer.apple.com/documentation/uikit/uitextview).

I'm not sure I understand this statement about combining the UILabel with TextField or TextView. There's no code showing how to do this so I can't test if it's a good a11y practice or not. It seems like an extra hack that's not required. I don't know what the behavior would be so I would avoid it.

pauljadam avatar Nov 09 '23 14:11 pauljadam

@pauljadam there is a code sample using UILabel + UITextField to show how one could provide labels for input fields.

label.text = "Name"
field.accessibilityLabel = label.text

It's consistent with the guidance provided for other frameworks. It's showing a basic way to provide an accessible input field.

JJdeGroot avatar Nov 10 '23 13:11 JJdeGroot

That part is fine, this part is the one I'm confused about?

We recommend combining UILabel with a UITextField or UITextView.

pauljadam avatar Nov 10 '23 13:11 pauljadam

The "combining" part is about using a UILabel as label for an input field, such as UITextField or UITextView. How could we word this more clearly? @pauljadam

JJdeGroot avatar Nov 14 '23 10:11 JJdeGroot

I was confused because I assume "combining" to me means to combine the focusable area of the 2 elements into one single element and my worry is that the label would not be focusable.

I would reword to say something like "Set the visible label text as the .accessibilityLabel of the input."

pauljadam avatar Nov 14 '23 14:11 pauljadam