dummy_ty
dummy_ty

Reputation: 41

Accessibility on custom UISlider

I have created a custom range UISlider with two thumb. However in VoiceOver mode, I am not able to swipe up and down to adjust the thumb.

UIAccessibilityElement *minElement = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self];
minElement.accessibilityFrame = [self convertRect:currentThumbRect
                                             toView:nil];
minElement.accessibilityLabel = NSLocalizedString(@"Minimum", nil);
minElement.accessibilityTraits = UIAccessibilityTraitAdjustable;

[_accessibleElements addObject:minElement];

UIAccessibilityElement *maxElement = [[UIAccessibilityElement alloc]
                                       initWithAccessibilityContainer:self];
maxElement.accessibilityFrame = [self convertRect:currentUpperThumbRect
                                            toView:nil];
maxElement.accessibilityLabel = NSLocalizedString(@"Maximum", nil);
maxElement.accessibilityTraits = UIAccessibilityTraitAdjustable;

[_accessibleElements addObject:maxElement]

I have added code above so that VoiceOver can recognize both thumb separately, but I couldn't adjust the thumb. Any idea to make the thumb adjustable in VoiceOver.


Problem Solved:

I use 'UIAccessibilityCustomAction' to add in custom behavior. Instead of slide up and down to adjust the value, in custom behavior slide up and down can be use to choose the action and double tap to perform it.

UIAccessibilityElement *minElement = [[UIAccessibilityElement alloc] initWithAccessibilityContainer:self];
minElement.accessibilityLabel = NSLocalizedString(@"Minimum", nil);
UIAccessibilityCustomAction *increaseMinAction = [[UIAccessibilityCustomAction alloc] initWithName:NSLocalizedString(@"Increase minimum", @"action to increase min")
                                                                                                 target:self selector:@selector(accessibilityMinIncrement)];
UIAccessibilityCustomAction *decreaseMinAction = [[UIAccessibilityCustomAction alloc] initWithName:NSLocalizedString(@"Decrease minimum", @"action to decrease min")
                                                                                                 target:self selector:@selector(accessibilityMinDecrement)];
minElement.accessibilityCustomActions = @[increaseMinAction, decreaseMinAction];
[_accessibleElements addObject:minElement];

Upvotes: 1

Views: 1908

Answers (2)

XLE_22
XLE_22

Reputation: 5671

You may use custom actions to solve your problem but I don't think that's the recommended solution for a UISlider with VoiceOver.

You were initally following the right path using the increment and decrement methods with the adjustable trait.

The problem dealt with your implementation : in my opinion, the best way is to define the former 2 methods so as to adapt the slider value according to the knob location.

Upvotes: 0

David Rönnqvist
David Rönnqvist

Reputation: 56625

An adjustable element will be called with accessibilityIncrement and accessibilityDecrement When the user swipes up or down. When that happens it is expected to change its accessibilityValue. If the value doesn't change, VoiceOver will interpret that as having reached the boundaries of possible values (either the lowest or heights value that's allowed) and will play a "ding" sound to indicate to the user that the gesture had no effect.

A plain UIAccessibilityElement doesn't (to the best of my knowledge) implement the increment and decrement methods and you don't seemt to be modifying the value of those elements. As such, when the user focuses on one of those elements, the method isn't implemented and the value doesn't change so VoiceOver plays the "ding" sound.

One possible solution is to subclass and have each knob element either hold the current value, or to have each knob element ask a delegate for the value and forward the increment and decrement methods to that delegate.

Upvotes: 2

Related Questions