0

I have a UITableView that displays a list of items, with a subclass of UITableViewCell. In that cell, I have a hierarchy of UILabels 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?

invalidArgument
  • 2,289
  • 4
  • 24
  • 35
  • Not 100% clear on what you want to change exactly, but have you looked at using `accessibilityElements`, or disabling accessibility on contained labels and setting the label on the container? – Wain Nov 17 '15 at 16:31
  • Right now, the user has to swipe 3 times to hear all the info of one cell (one for the top-level labels, and once for each `UIView` subclasses). I want all the info to be said on the first swipe. In my testings, setting `accessibilityElements` make VoiceOver say only one info at a time (so a user would have to swipe 7 times in my example). I hope this adds clarity to the question! – invalidArgument Nov 17 '15 at 17:46

2 Answers2

4

I think what you are after is:

  1. set isAccessibilityElement = true on the UITableViewCell
  2. set accessibilityLabel 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 :-)

Boris Dušek
  • 1,272
  • 11
  • 12
  • I missed step 1 in my different tests. I was already customizing the string that needed customizing as per your suggestion, but indeed it makes a big difference! – invalidArgument Nov 17 '15 at 17:57
  • I find it better to override the accessibility label property, and collect the labels of the subviews. This way it responds properly to dynamic changes of its children. – MobA11y Nov 19 '15 at 04:30
  • Have you come up with a generic way to collect the Accessibility labels of subviews? this is a recursive task by design, and not too easy to combine together in a localized way. I'd be happy to see a sample of how you did it. – Motti Shneor Dec 14 '16 at 10:01
-2

And there is another place, in your subclass, override method:

-(BOOL) isAccessibilityElement {
    return YES;
}
BollMose
  • 3,002
  • 4
  • 32
  • 41