I am making my iPhone app accessible. VoiceOver is pretty impressive. When a user uses VoiceOver, it automatically reads off the items on the screen and allows the user to double-tap anywhere on the screen to select that item. However, I want VoiceOver to read the items in a specific order, but it always begins with the UINavigationBar items including the back button. I don't want these items not to be read at all, I just want to start with a specific item. Is there a VoiceOver-equivalent of "firstResponder"?
A Boolean value that indicates whether the element is an accessibility element that an assistive app can access.
To successfully group accessibility elements, the key is to wrap them all in some sort of a “container” view, and then set an array of child elements on that container view's accessibilityElements property.
A Boolean value that indicates whether VoiceOver groups the accessibility elements that are children of the element, regardless of their positions on the screen.
There is a protocol called UIAccessibilityContainer
that is implemented by NSObject. It enables you to customize the container behaviour using these three methods:
accessibilityElementCount
accessibilityElementAtIndex:
indexOfAccessibilityElement:
If you have a main view where you want to control the order of the accessibility elements you would just implement these three methods and return the suitable view/index. One more thing is that the container view cannot be an accessibility element itself so you should override isAccessibilityElement:
and return NO
;
- (BOOL)isAccessibilityElement {
return NO;
}
I suggest that you either have an array of all the views in the order you want them to appear or use the tag
property if you don't use it for anything else. The implementation of the protocol becomes super simple.
I'm assuming that you have an array called accessibleElements
that store the elements in the correct order.
- (NSInteger)accessibilityElementCount {
return self.accessibleElements.count;
}
- (id)accessibilityElementAtIndex:(NSInteger)index {
return self.accessibleElements[index];
}
- (NSInteger)indexOfAccessibilityElement:(id)element {
return [self.accessibleElements indexOfObject:element];
}
I'm assuming that your subviews are tagged continuously from 0 up to the number of subviews.
- (NSInteger)accessibilityElementCount {
return self.subviews.count;
}
- (id)accessibilityElementAtIndex:(NSInteger)index {
// Not that self should have a tag<0 or tag>count otherwise it will
// return itself for that tag instead of the element you want it to.
return [self viewWithTag:index];
}
- (NSInteger)indexOfAccessibilityElement:(id)element {
return ((UIView *)element).tag;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With