I have a problem with how VoiceOver announces my custom UITextInput while it has the keyboard focus: When the accessibility focus is moved to the UITextInput view by swiping left/right the UITextInput is correctly announced by VoiceOver and I am hearing something like Text field, is editing, <content of text input>, character mode, insertion point at end.
However, if I move the accessibility focus to the UITextInput by tapping on it, VoiceOver says empty line, which is not correct.
I would expect VoiceOver to make the exact same announcement regardless of how the UITextInput got the accessibility focus.
Any ideas what might be the cause of this strange behavior?
To mark up a text field you need to take advantage of a few different properties. First, the "Text field" part you can only get by having your custom control extend the UITextFIeld class. That's the only way you can get that announcement at the beginning without effecting the read out of other things. You could append this to the label. Here are the properties I would recommend for your custom text editor.
Preferred Markup
ClassType: Subclass of UITextField (Probably the most important piece)
AccessibilityLabel: The thing the entered text represents (Ex: Password, Username, etc).
AccessibilityValue: The entered text.
AccessibilityHint: "Some non critical information, that shares some details about what the entered information will be used for."
AccessibilityTraits: (NOT Static Text Trait)
Note that the hint isn't crucial information. Hints are frequently ignored, and just contain useful clarifying information.
Aleternate markup (NOT RECOMMENDED)
ClassType: Subclass of ????
AccessibilityLabel: Text field, $EditingState, $EnteredText, $InsertionPoint
AccessibilityValue: nil
AccessibilityHint: nil
AccessibilityTraits: StaticText (Weird, but if you're including role information yourself, we want the trait of static text on an editable text field, to avoid VoiceOver being smart, including it, and duplicating role information in the announcement... is this starting to feel like a hack yet???)
This is honestly a terrible idea, you really should just have your TextField inherit from the system UITextField and get all of that stuff for free, but if you must, this is how you wold achieve... similar behavior without doing so. I say similar because there are a few things you CANNOT replicate in a custom control.
keyboard type ("character mode") is more painful for you to grab than the system, and I recommend omitting in the custom case. The keyboard doesn't have to respect your requests for mode changes (custom keyboards and such), you can get into trouble and confuse users attempting to share this based on your application's settings. The system is the only thing that can get this right in all scenarios.
Inflection. By doing this the custom way you will lose the style and inflection from VoiceOver. The pauses between the Label and the Entered Text. The lower voice that is read when the placeholder text is read out, etc. You can add commas to your AccessibilityLabel to somewhat replicate some of this, but ultimately, your custom control will always sound a little "off" to a VoiceOver user... unless your custom view extends UITextField...
Related
I'm trying to optimize my app. What is the best practice method for implementing accessibility in iOS with accessibilityLabel and accessibilityHint? Are accessibility labels always required?
My app is very dynamic and objects in the view get updated frequently depending on the user's action. For example, a view might start off as one shape and later turn into another shape. Accordingly, the accessibilityLabel and accessibilityHint of each object is updated frequently to reflect the changed view for users with VoiceOver turned on.
Questions
Is it safe to expect that when VoiceOver is not running (i.e. !UIAccessibilityIsVoiceOverRunning()) then setting
accessibilityLabel and accessibilityHint is completely
unnecessary?
Are there assistive technologies other than VoiceOver that a user might use that access accessibilityLabel and accessibilityHint?
What is the best practice method for implementing accessibility in iOS with accessibilityLabel and accessibilityHint?
You should consider, rather than "setting" the accessibility label, overriding the property implementation. Allow the view that requires an accessibility label to calculate its value when required, rather than keeping the value in sync constantly. Much easier! You would do so with code that looks like this.
override public var accessibilityLabel: String? {
get {
return "Calculated label"
}
set {
//Specifically do nothing. We're not "setting a property" we're responding to changes of the internal views.
}
}
Are accessibility labels always required?
Yes and no. Accessibility labels are always required for elements that present information and are individually focusable (you may have a group f controls, wrapped in one layout, with one accessibility label). I can say with reasonably certainty that in the context of your question, removing the accessibility label is absolutely the incorrect thing to do.
Is it safe to expect that when VoiceOver is not running (i.e.
!UIAccessibilityIsVoiceOverRunning()) then setting accessibilityLabel
and accessibilityHint is completely unnecessary?
No, there are other uses for accessibility properties outside of VoiceOver.
Are there assistive technologies other than VoiceOver that a user
might use that access accessibilityLabel and accessibilityHint?
There are certainly assistive technologies outside of VoiceOver, and they are dependent on a a myriad of accessibility properties. (braille boards, switch access, etc)
Conclusion
It seems to me like you are trying to get around accessibility as a software practice and rationalize doing so. This is the wrong thought process. HOWEVER, it may indeed be impractical to make the view that you have accessible because of some fundamental design problem. You should consider whether or not the thing you have is designed in a way that it can be made accessible from a development/API point of view. The APIs do limit you from accomplishing certain things. Whether or not your up against one of these limitations is NOT a question you can ask on StackOverflow and the solution is NOT to omit accessibility information. It is to redesign the control OR perhaps to provide an alternate accessible implementation... though this route should be considered VERY carefully. In general separate is not equal.
Currently I am walking through my whole iOS app to optimize it for accessibility voice over. When it comes to the UITextView, which I subclassed, voice over is not acting like I thought it would. My UITextView subclass is only changing a path's color on the superview's layer in becomeFirstResponder and resignFirstResponder. So nothing special on my UITextView subclass that could interfere with accessibility.
As long as there is no text in the UITextView it is acting as expected. Voiceover tells me that it is a text field and that I can double tap it to edit. But as soon as there is text in the UITextView, the only thing voice over tells me, is the value of the UITextView. Voice over doesn't tell me anymore that this is an editable text field.
Am I doing something wrong? Why is it acting like that?
I do appreciate any help!
If you didn't edit any accessibility hints or labels for the text field it should act accordingly. If selected it should say:
It is a text field
If you are editing it
The editing mode you are in
The value of the text field (nil if empty)
Where the cursor is
Then while you type it says the letters you are entering as you enter them. When you hit space or enter it should say the word you just typed. As long as your text field is exhibiting these behaviors you should be fine.
Tip: if you want to know how accessibility elements should act, try using a native iOS app with accessibility turned on and compare it with your app.
With UIAccessibilityFocus protocol, supposedly, if you override accessibilityElementDidBecomeFocused() and accessibilityElementDidLoseFocus(), you will be able to track when an accessible element gain or lose focus while Voiceover is running. This seems to work well with all field types - UIButton, UILabel, UISwitch, UITextView, etc. - except UITextField. When Voiceover focus is on (or leaving) an UITextField, those functions are simply not called. Just wondering if it is a bug or something else. Thanks!
This is a feature, let me explain.
Without VoiceOver turned on there is no concept of focus within iOS. Except in the case of UITextField. UITextFields get "focused" (again focus isn't really a concept in iOS without voiceover) with or without VoiceOver on. For the other elements, this is not the case. They do not have "gainFocus" equivalents. A UIButton gaining focus is only meaningful from an accessibility standpoint. So they add in the special accessibilityElementDidGainFocus calls for those classes. They are specifically removed from UITextFields because that call would be logically equivalent to calls that already exist for that class, independent of the Accessibility API.
I have developed an IOS 8 custom keyboard. I want to give it "undo" and "redo" functionality, like the default system keyboard. I have tried it in different ways but was unable to find a good solution.
We can interact with a Text Input Object textDocumentProxy with the methods
insertText
deleteBackward
documentContextAfterInput
ocumentContextBeforeInput
But I was unable to find any way of implementing "undo" and "redo" functionality.
I think we can NOT implement these function (undo,redo)
According to https://developer.apple.com/library/ios/documentation/General/Conceptual/ExtensibilityPG/Keyboard.html
Because a custom keyboard can draw only within the primary view of its
UIInputViewController object, it cannot select text. Text selection is
under the control of the app that is using the keyboard. If that app
provides an editing menu interface (such as for Cut, Copy, and Paste),
the keyboard has no access to it. A custom keyboard cannot offer
inline autocorrection controls near the insertion point.
I think there are many case that content of textfield changed and you can not know when it changed, how it changed. If we can not know, we can not know to undo to where too. I think so.
I'm developing Custom keyboard extension like you and I have many problems. (eg: how can we know the current cursor to get current text selection...)
My question: Current text selection in CustomKeyBoardExtension (hope somebody know)
Has anyone run across this warning message building for the iPhone?
More importantly do you understand how to fix it?
"unsupported configuration data detection and editable"
It's seems to be the UITextView that is complaining.
Here's a screenshot.
The problem is that you have that textview set both to editable + to detect/autolink phone numbers, events, addresses, etc. a text area can either be editable and not detect/autolink text, or it can autolink text but not be editable.
Your settings for that textview should look like:
or
but not like:
I think in your scenario, the text input is only used to input text, nothing more. Then when it get's presented back, the "presenting text view" will take care of detecting the potential information... dates, events, etc.
To be more precise : in a simple app scenario, a user types in some text (let's say an event input text view - with no detection necessary at this point). Then when it get's eventually presented back to him or another user (let's say the detail view of the event), the text will be presented back in a "non-editable" text view that in turn will be able to have detections.
I know this question is a little old, but this is how I resolved it;
In Interface Builder I have Links Detection selected, and Editable Behaviour not selected.
Then, in my ViewController, I implemented the UITextView - (BOOL)textViewShouldBeginEditing:(UITextView *)textView { } delegate method and return NO.
It removed the warning and prevents the user from being able to edit the UITextView's content.