I have a UITableView
that displays a list of items, with a subclass of UITableViewCell
. In that cell, I have a hierarchy of UILabel
s and subviews like so:
UITableViewCell subclass
- UILabel a
- UILabel b
- UILabel c
- UIView subclass 1
- UILabel 1a
- UILabel 1b
- UIView subclass 2
- UILabel 2a
- UILabel 2b
I'd like VoiceOver to read all the labels in the order presented here. I should note here that visually, the labels in the UIView
subclass are in reversed order (UILabel
1b is on top of UILabel
1a, for example).
Some labels need to have the 'accessibilityLabel' property set to some custom string. It is done in the configuration of the UITableViewCell
, once the text is known, either to labels directly or to subviews. I also set the shouldGroupAccessibilityChildren
property to YES.
Right now, the behaviour I have is: VoiceOver reads the top-level UILabel
(a, b & c in the example). Then if I swipe to get the next element it reads UIView
subclass 1, then 2, etc. When reading those subclasses, the order of reading is fine (UILabel
1a, then 1b, etc.).
Can I achieve this? Or does the user absolutely needs to swipe?
I think what you are after is:
isAccessibilityElement = true
on the UITableViewCellaccessibilityLabel
to whatever you want on the UITableViewCell
This will present the whole UITableViewCell
as a single element to VoiceOver (step 1.) (this is great as navigation with VoiceOver over a list of such cells is much more efficient and user-friendly), and allow you to customize exactly what VoiceOver says for the cell (step 2.).
Note that in step 2., you can be also a little bit more creative - not just say all labels in desired order separated by commas, but also adding some words to make it more user-friendly (though I would advise to be a bit conservative here to not get into situation where the presentation would be too "chatty", especially if the user quickly goes through several such cells in succession when searching for something - too chatty label can become tiresome). E.g. if it was a shopping app, instead of "Bread, USD 1, in stock" (i.e. just concatenate 3 labels and separate with comma), you could say "Bread for USD 1, in stock" (String(format:)
in Swift and [NSString stringWithFormat:]
in Objective-C are your friends here; don't forget to localize the format string).
Of course, if you later need to have some buttons in the cell later, it becomes a bit more complicated. But that is for another question :-)