Is there any way to have VoiceOver read a label on command? - ios

I'd like to have my QR code scanning app inform the user when it finds a QR code. For sighted users, this works using a label at the bottom that updates to notify the user. However, a blind user would have to tap on that label again to have it read by Voice Over. I would much prefer it to just read automatically.
The closest I can find to this question is
UIAccessibility - Read all the labels and buttons on the screen from top to down, which wasn't possible. While this doesn't bode well for my app, that was a year ago. Has Apple updated it's UIAccessibility protocol in any way to allow this?
As a last resort I suppose I could play my own mp3 recording if VoiceOver is on.

You can make VoiceOver speak any string any time you want by calling:
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, NSLocalizedString("QR code has been detected", comment: ""))
Swift 4
UIAccessibility.post(notification: .announcement, argument: "Text")
There is no direct way to tell VoiceOver to speak updates of an element that VoiceOver cursor is not on. This (i.e. speaking the same content "manually") is a feasible workaround.

You can move VoiceOver focus to an element by using the following:
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, elementToFocusOn)
VoiceOver will then parse and read the accessibility properties associated with that element.

Related

VoiceOver does not repeat typed character on custom text view with UITextInput

I have custom text view that implement UITextInput. Everything works except the voiceover does not repeat the characters I typed using soft keyboard.
Is there any additional API or services I need to implement in order to make it work?
Unfortunately, now it seems that VoiceOver cannot announce the soft keyboard feedback made by native code.
But it possible to get VoiceOver feedback at text field of WebView().
So, I'm making iOS App by this way.

Prevent Voiceover from reading UIAccessibility accessibilityLabel

I have a custom UIView subclass that displays text. The text can be in various languages, and I have audio for it. I don't want Voiceover to ever attempt to read the text itself, because I want the users to here my audio. I can set the accessibilityLabel of the element to an empty string, and play my audio in accessibilityElementDidBecomeFocused. However, I'm worried that this will be an issue for some users, because an alternative display wouldn't know how to display the text, the Item Chooser won't show the item, and I'm sure some other issues I haven't thought of.
Basically, I want to be able to give an accessibility element an accessibilityLabel, and have it be an active accessibilityElement, but NOT have VoiceOver read the label on focus.
As far as I know, this is impossible using current APIs. While you can change content when VoiceOver is running, you cannot distinguish how that content will be presented to the user, whether through speech, Braille keyboard, or other means.
Consider filing an enhancement request with Apple.
I asked a similar question in accessibility-dev#lists.apple.com and it was pointed out to me that Voice Over users set their personal playback voice and speed. Replacing it with your own audio will likely have a detrimental effect.

How do I support VoiceOver in UIPickerView on an iPad running an iPhone only app (non-universal)?

Generally I look at Apple's UICatalog sample code for basic VoiceOver support however it looks like there is VoiceOver support for UIPickerViews in the sample code. Do I need to provide an accessibilityLabel method somewhere to add VoiceOver support? I tried to implement UIPickerViewAccessibilityDelegate methods but voice over only reads the labels in my picker view and not the hint to swipe up or down to change the values.
Also my picker view is set to the input view of a UITextField. So I'm not sure if that is relevant or not.
Update:
https://github.com/stevemoser/VoiceOverPicker
I created a sample project demonstrating the issue. In the example there is a normal picker view shown and a textfield. There is also a picker that is set to the textfield's input view property. I can't seem to activate the either picker just by tapping on it while using VoiceOver. Though I can activate either one by swiping (left and right) through the views on screen. Any ideas?
Update 2:
Looks like if the app is an iPhone app running on an iPhone or an iPad app running on an iPad it works fine but if it is an iPhone only app running on an iPad, tapping to select a UIPickerView doesn't work.
Are you just doing a vanilla UIPickerView using titles for each row (and not custom views)? If so, there isn't anything that you should have to do.
You mentioned that VoiceOver was correctly reading the label on each row, so we know that the UIPickerView correctly has isAccessibilityElement set to YES. It's also correctly reading the accessibilityLabels.
Is it possible that you're interacting with the picker before it has a chance to read the accessibilityHint? (For the benefit of others, the accessibilityHint is the "swipe or down with one finger to adjust the value" that Steve mentioned in his question.) Or perhaps some notification is changing the VoiceOver focus before the hint has a chance to be read?
By default, if your picker view is accessible, when you focus on it with VoiceOver it will read the something along these lines:
"[ROW LABEL] Adjustable [#number] out of [#total] picker item" a 2 to
3 second pause then "Swipe up or down to select value"
A few of things to note:
There is a 2 to 3 second delay between reading the label and the hint, make sure you wait for it.
If you're providing your own hint, the default one will not get read I believe
Hints are only read when you reach a certain control by either directly pressing it or by swiping right or left to the control. it will not get read if you do a 2 finger swipe down or up.
Make sure you're testing on an actual device and not a simulator as it does not show all of the things VoiceOver announces.

How to make long text accessible

I'm trying to make my app more accessible but I have a problem. Part of my app consists of pieces of advice, each composed of an UIScrollView with long text. (The text is a UIImage I prepared with Photoshop ).
I would like to make it accessible so that the users could listen to all the advice and pause it whenever they want. I thought of using UIAccessibilityLabel but the text is too long.
Thanks in advance for your help.
Let me preface this by saying I am not an iOS developer but am a long time blind iOS user.
There is no way to easily pause the reading of text and resume at the exact same spot that I know of. According to the documentation, I've found accessibilityLabel is meant to provide accessibility information that can be conveyed in under a sentence. An option I can think of would be to test whether VoiceOver is enabled using UIAccessibilityIsVoiceOverRunning. If this is true, you could put your text into a text view, and display that instead of your UIImage.
A textView will allow a VoiceOver user to read the text by character, word, or line, which is the best option available. If VoiceOver isn’t running, your test will return false, the UIImage will be displayed as normal, and the user won’t see anything different.

Can I tell iOS when it's in VoiceOver mode to read aloud a specific UILabel's text when I change it?

I've got a label that's going to change to say something silly like "the sky is now blue" and I'd like to have VoiceOver read that new text aloud without a semi-blind user needing to press on the label.
Is that possible however, to direct VoiceOver to read a specific item when & where I want?
Thanks.
See this answer: iPhone - make VoiceOver announce label text change
In short, you can tell iOS to speak text aloud when in voiceover mode by sending notifications, like:
UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, #"the sky is now blue");
I'm still trying to figure out how to "focus" on a particular UIAccessibilityElement (i.e. make it as if they had tapped it), but I think in your case you could use UIAccessibilityAnnouncementNotification to speak arbitrary text.

Resources