0

I have a selector control in my app based on UITableView. The user can scroll the table view and a marker in the center shows selected item. Every selectable item is a table view cell.

Example

Now I want to make my app VoiceOver compatible for a friend. But this control, I have trouble make it work.

With VoiceOver on, I can't scroll the table view to select other elements. I looked at picker view in clocks app. It does not scroll too. But when you flick up or down it jumps to the next or previous value. It says

"swipe up or down with one finger to adjust the value".

I read Matt Gammell's VoiceOver guide where he sais the hint must say what the control does not what you should do.

So I infer this is a special trait they use for things that can swipe up or down to adjust value. But I cant find such trait.

Since UIPickerView is based on UITableViews how did Apple make it work with VoiceOver? Must I use gesture recognizer for flick?

Edit

I am setting the adjustable trait on the UITableView subclass like this:

self.isAccessibilityElement = YES;
self.accessibilityLabel = @"Start date.";
self.accessibilityTraits = UIAccessibilityTraitAdjustable;

The table view implements

- (void)accessibilityIncrement {
    NSLog(@"accessibilityIncrement");
}

- (void)accessibilityDecrement {
    NSLog(@"accessibilityDecrement");
}

Now I can drag across cells and VoiceOver will read their labels and mark them with the black rectangle. But table view does not scroll and the methods above don't get called.

The cells themselves are isAccessibilityElement = NO; and don't implement accessibility action methods.

Adil Hussain
  • 30,049
  • 21
  • 112
  • 147
openfrog
  • 40,201
  • 65
  • 225
  • 373
  • 3
    It's better to use `self.accessibilityTraits |= UIAccessibilityTraitAdjustable;` so that you *add* the adjustable trait instead of setting it. That way you won't overwrite any existing traits. – David Rönnqvist Jul 26 '13 at 06:32
  • Great tip, thank you David. Is there also a trick to remove a trait? – openfrog Jul 26 '13 at 07:57
  • 3
    They are just bitmasks so you would use "binary and" with the inverted value `self.accessibilityTraits &= ~UIAccessibilityTraitAdjustable` to remove a single trait – David Rönnqvist Jul 26 '13 at 08:07

2 Answers2

2

You are looking for the adjustable trait: UIAccessibilityTraitAdjustable.

If you specify this trait on your view/cell you must also implement accessibilityIncrement and accessibilityDecrement in that view/cell. These are the two methods that get called when the user swipes up and down with one finger.

There is no need to implement any gesture recognizers yourself. Setting the trait is enough to get that behavior (it will also add the "swipe up or down with one finger ..." description)

David Rönnqvist
  • 56,267
  • 18
  • 167
  • 205
  • 1
    Updated question with code example. Do I set this trait for each UITableViewCell? Or is it sufficient to set it for the UITableView itself? I set it on the UITableView and implemented accessibilityIncrement and accessibilityDecrement. But the methods don't get called. – openfrog Jul 25 '13 at 23:47
  • Think about it. What element should behave like it's adjustable? It's either the cell or a subview of the cell. That cell/subview should implement these method since they will be called on that element. – David Rönnqvist Jul 26 '13 at 06:30
  • But the table view is the master with the logic to handle the selected item. It knows which row is in center. Like in Weightbot but vertical. – openfrog Jul 26 '13 at 07:59
1

You add the UIAccessibilityTraitAdjustable to the element's traits. Then you implement the -(void)accessibilityIncrement and -(void)accessibilityDecrement actions. In the case of the date picker, you should do this for each component (year, month, date) - each of these is an element (which the user can move the VoiceOver cursor to by flicking left and right) and each is adjustable (by flicking up/down while the VoiceOver cursor is on it).

Boris Dušek
  • 1,272
  • 11
  • 12