Accessibility on UIStepper - ios

I know that voiceover can a be bag of hurt when used with an UIStepper because the UIButtons that it contains can't be customised. However I use this control to change a value displayed on a label:
I don't want to insert a new control just for voiceover and subclassing a control like UIStepper doesn't seem a good solution. Any ideas to implement voiceover with this interface?

You could have a view which wraps your label(s) and stepper together and which deals with the accessibility. So, the subviews are all disabled for accessibility and the wrapper view presents the text in the labels, the current value of the stepper and provides / handles a swipe based interface to increment and decrement the stepper. So, overall, the wrapper view would work like a slider.

An interface implementing a stepper may be well vocalized and presented by VoiceOver using the adjustable values.
A complete explanation is detailed here including illustrations and code snippets (ObjC + swift).

Related

Custom Keyboard Accessory view input

I have created a custom accessory view to supplement the standard Apple alpha iOS keyboard.
The purpose is to add a line of numeric keys to prevent flipping back and forth between keyboard views. At first, I created a toolbar and loaded it with a set of 0 - 9 titled buttonItems and it functioned quite well. However, it looked terrible, not at all like the alpha keys despite adding a rounded rect background image to each key because the system apparently prevents customizing font size and button spacing inside the stack view of the toolbar. Therefore, I created a UIView xib and loaded it with a stackView full of customized numerical buttons. When I add the UIView as the accessory view it looks pretty darn close to the rest of the Apple Alpha keyboard. The issue now is that the touch-up events go to the UIView class of the accessory view. Is there a clever, efficient way to have the button presses in the accessory emulate the std keyboard feeding into TextField: shouldChangeCharactersIn? I could package the button presses into a local notification event to get it into the class holding the textField but that seems terribly inelegant! Any suggestions would be greatly appreciated. Stay Safe!
Not the best answer, but I did implement notification on key button press with an observer in the main view class. The observer does a TextField.insertText which is suboptimal since I will need to refactor the several hundred lines of code that performs real-time language translation in the shouldChangeCharacters methods. Ah well.

ios voiceover slider double tap and hold, but for custom view

I've created a custom view that acts like a UISlider - there is a "track", and a handle to "grab" to change the value. For particular reasons, I can't just make it a subclass of UISlider. I'm trying to make this slider as accessible as possible with VoiceOver. I have accessibilityIncrease and accessibilityDecrease on my custom view that handle single finger drag up and single finger drag down. This changes the value of the slider by 10% at a time.
However, I'd like to allow more fine grained control, just like a non-VoiceOver slider. By default , UISlider has double tap and hold, and you can drag up/down to "pan" the slider. I'd like to add exactly that to my custom view, but I can't find the correct incantation to handle the double tap and hold gesture.
Is there something I can do to mimic the double tap and hold gesture from UISlider on my custom view?
Thanks very much!!!
If you want to implement this kind of new gesture for VoiceOver users, just forget it.
The recommended gesture for this kind of UI control is definitely the implementation of adjustable value as you already did apparently.
I don't think it's a good idea to try and implement new VoiceOver gestures in an application because its users have their habits and they may be totally lost with your customed control if they cannot handle it unless you add an hint to explain but that's definitely not what I recommend anyway.
Otherwise, you could take a look at the pass through concept introduced in the What's New in Accessibility WWDC 2017 video that deals with the same idea but for a panning gesture...

Prevent UISegmentedControl segment selection on focus on tvOS

I'm working on a simple UI on a tvOS app and I'm facing a strange problem.
When a UISegmentedControl get focused you can move your focus around and it automatically changes the selected segment. But what I'm looking for is a way to limit the segment selection only when the user taps the segment, not when he focused it.
Any idea?
Thanks in advance.
You need to have your own internal variable for the selected segment and only change its value when the select button is pressed (which you can get using a gesture recognizer). When the segment loses focus (detectable in didUpdateFocus function) you assign the value of your internal variable to the selected index of the segment control.
You need to subclass UISegmentedControl then override didUpdateFocusInContext. In the "Custom Class" field in IB use the name of your custom class.
You can subclass UISegmentedControl and disable the behavior by defining:
#objc func _selectFocusedSegment(){
print ("select focused segment")
}
Beware that this solution is a hack. As far as I know there is no good, clean way to accomplish what you want short of steering clear of UISegmentedControl.
Also know that when a UISegmentedControl 'changes focus' between segments, it does not actually change focus. So hooking into focus updates like Nostradamus is suggesting will not work. To the focus engine UISegmentedControl behaves like a single large focusable element, not like a group of focusable segments. You can see this for yourself by debug inspecting a UIFocusUpdateContext on focusing towards or away from a UISegmentedControl.
I stumbled onto _selectFocusedSegment by defining a UISegmentedControl subclass and debug logging the various NSObject.perform methods, among others. My intent was to reverse engineer how UISegmentedControl retains a sticky last focused item, which is quite difficult to do on Apple TV. I was not able to find out exactly how UISegmentedControl manages focus, but I was able to find the answer to your question along the way.

Swipe to switch focused accessibility element iOS

When the user has Voice Over on in certain apps, a one handed swipe to the right or the left changes the focused accessibility element and speaks it (for example, the App Store top charts view). I would like to have this in my own app (which uses a storyboard).
I can think of several ways to do this myself with a swipe gesture recognizer and a list of accessibility elements in order, but it seems like there must be a way to do this in the accessibility API. However, my research has turned up nothing.
Is this a built in feature? If so, how can I add it in my storyboard or in code?
Edit:
Per advice from one of the answer I have implemented the UIAccessibility protocol for my view.Here is the code.
- (NSInteger)accessibilityElementCount{
return 4;
}
- (id)accessibilityElementAtIndex:(NSInteger)index{
return [#[self.menuButton, self.firstButton, self.secondButton, self.thirdButton] objectAtIndex:index];
}
- (NSInteger)indexOfAccessibilityElement:(id)element{
return [#[self.menuButton, self.firstButton, self.secondButton, self.thirdButton] indexOfObject:element];
}
The view I am having this issue with is defined in an interface builder storyboard. As you can no doubt infer from the code, it has 3 buttons as subviews.
What you are describing is the built-in behavior for VoiceOver and can't be changed on a per-app basis.
If you want to modify the order elements are focused, look at the UIAccessibilityContainer protocol for iOS 7 or accessibilityElements property of NSObject for iOS 8. If you don't want to implement either of those, you can also simply set accessibilityElementsHidden to YES for elements you want VoiceOver to ignore.
I have fixed the problem by adding accessibility labels to the buttons in the storyboard. Because voice over already spoke their label correctly, I had not bothered to do so before.

What makes an element accessible? And why are tap gestures less accessible than UIButtons? How do I fix it?

Brent Simmons wrote in a blog post that tap gesture recognizers, presumably on a UIView, are less accessible than UIButtons. I'm trying to learn my way around making my app accessible, and I was curious if anyone could clarify what makes that less accessible than a UIButton, and what makes an element "accessible" to begin with?
For more customizability I was planning to build a button comprised of a UIView and tap gesture recognizers with some subviews, but now I'm not so sure. Is it possible to make a UIView as accessible as a UIButton?
Accessible in this context most likely refers to UI elements that can be used using Apple's accessibility features, such as VoiceOver (see example below).
For example, a visually impaired person will not be able to see your view or subviews, or buttons for that matter; but the accessibility software "VoiceOver" built into every iOS device will read to her/him the kind of object and its title, something like "Button: Continue" (if the button title is "Continue").
You can see that most likely the tap gesture recognizer will not be read by VoiceOver and thus be less "accessible".

Resources