0

A single swipe gesture is intended by Apple to move the VoiceOver cursor through screen items in order but mine don't because the user can move them around!

My main view has a set of buttons and labels, however it also has two collections of custom subviews, let's call the instances SVA1 to SVA9 & SVB1 to SVB9 in 'ascending order' from left to right. That is, SVA is one custom UIView class and SVB is the 2nd. When I drag, say, SVA3 to the current position of SVA6 then I end up with an order of SVA1, SVA2, SVA4, SVA5, SVA3, SVA6, SVA7, SVA8 & SVA9. The collections are 'linked' so that that same order would now also be mirrored in the SVB subview collection via my code.

My problem is that swiping to the right, expecting VoiceOver to read out my items as I see them on screen results in a different order. It gets quite a lot of them right but then will suddenly move the VoiceOver cursor from the first collection to the 2nd or change its direction. After a move my code is aware of the new order of all the subviews but I'd like to be able to get that information to VoiceOver.

Each custom subview is an accessibilityElement. Is there a way that I can tell VoiceOver to read back my items in the order I'd expect? I've come across the -accessibilityElementAtIndex: method but don't see whether or how that fits with my situation.

Thank you.

Stephen Watson
  • 1,700
  • 16
  • 17

1 Answers1

2

If you want to change the order then accessibilityElementAtIndex: and the rest of the UIAccessibilityContainer protocol is what you are looking for.

Assuming that you have an array called accessibleElements that store the elements in the order you want them to appear.

- (NSInteger)accessibilityElementCount {
    return self.accessibleElements.count;
}

- (id)accessibilityElementAtIndex:(NSInteger)index {
    return self.accessibleElements[index]; 
}

- (NSInteger)indexOfAccessibilityElement:(id)element {
    return [self.accessibleElements indexOfObject:element];
}

The container can't be a accessibility element itself so you should also override isAccessibilityElement

- (BOOL)isAccessibilityElement {
    return NO;
}
David Rönnqvist
  • 56,267
  • 18
  • 167
  • 205
  • 2
    As of iOS 8 you can set an object's `accessibilityElements` directly without overriding `accessibility{ElementCount|ElementAtIndex:|IndexOfElement:}`. – Kasper Munck Aug 26 '15 at 07:24