15

In Calendar, when you create a new event, if you tap on the All Day cell with VoiceOver enabled, Siri says "All Day switch button on/off, double tap to change setting". And indeed double tapping will toggle the switch. Also, it's not possible to tap on just the toggle switch itself - you have to interact with the cell itself to toggle the switch, the switch itself is not an accessible element.

In my app I have the exact same setup with a label and a switch. But when I tap the cell with VoiceOver enabled it only reads the label so the blind user has no idea there's a toggle switch in that cell. If they tap the switch itself then they can interact with it, so it's the opposite of the setup in the Calendar app.

How can I obtain the same behavior that Apple implemented? I need some way to combine the switch into the cell so VoiceOver reads both upon highlighting the cell, then when they double tap it should toggle the switch, and I'm not sure how that setup can be accomplished. Thanks!

mfaani
  • 33,269
  • 19
  • 164
  • 293
Jordan H
  • 52,571
  • 37
  • 201
  • 351

3 Answers3

13

To implement the desired behavior, instead of placing the UISwitch in the contentView of the cell, add it as the accessoryView programmatically. Then the cell and switch will behave exactly as expected when using VoiceOver, exactly as it does in Calendar.

Jordan H
  • 52,571
  • 37
  • 201
  • 351
  • 1
    You answer helped me. Unfortunately it works only with `UISwitch` and not `UISegmentedControl` – Boris Y. Oct 02 '14 at 20:09
  • 2
    @borisy You can subclass UITableViewCell and implement accessibilityActivate() to achieve the same effect with a UISegmentedControl. It takes a bit more work than with UISwitch, but it can be done. – Daniel Nov 14 '16 at 03:42
3

I would like to elaborate on the answer of Joey, and clarify how a solution to this question can be achieved in code.

In the tableView:cellForRowAtIndexPath:, create a custom UISwitch view and append it to the accessoryView of the cell. This could look something like the following.

UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
[switchView setOn:NO];
[switchView addTarget:self action:@selector(selector:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = switchView;

return cell;

The cell will now behave like any native iOS switch known from e.g. Settings or Calendar. Double tapping on the cell with VoiceOver enabled, will now toggle the UISwitch (on/off), and VoiceOver will automatically notify the user about the state of the switch, together with an accessibility hint.

Community
  • 1
  • 1
2

You should be able to set a custom accessibility description on the cell using

cell.accessibilityLabel = @"Double tap to toggle setting";

You can set up custom gestures for when VoiceOver is running according to this answer:

https://stackoverflow.com/a/12337128/567511

But here you would not need custom gestures, instead your didSelectRowAtIndexPath would flip the switch only when UIAccessibilityIsVoiceOverRunning is true.

Community
  • 1
  • 1
nagem
  • 158
  • 2
  • 8
  • 1
    Just doing that would be bad, since double tapping will not actually toggle the setting. And the text that states you can double tap to change the setting is already included when the user taps on the switch. I need some way to combine the switch with the cell so triggering the cell will toggle the switch instead of selecting the row. – Jordan H Jun 30 '14 at 21:15
  • Sorry, I misunderstood that you also didn't have that part working yet. Please see my edit. – nagem Jun 30 '14 at 21:22
  • Thanks for that. I could do that but also highlighting the cell should tell the user about the switch and its state (on or off). This needs to be dynamic so I can't define a static NSString for the accessibilityLabel. Is there not a way to "combine" the cell and switch into one so it reads one followed by the other exactly as it does in Calendar? I wonder how they implemented it. I wonder if adding the UISwitch as an accessoryView would be the solution? I just dragged it in and positioned it in the custom cell. – Jordan H Jun 30 '14 at 21:45
  • Just wanted to add that an accessibilityLabel should represent the content of the cell, not the action to perform. Once the custom gesture has been added, you can inform VoiceOver users how to interact with the cell using accessibilityHint: cell.accessibilityHint = @"Double tap to toggle setting"; – Jon Gibbins Apr 02 '15 at 11:00
  • @nagem, what will be the french text for `Double tap to toggle setting `? – pkc456 Jul 25 '19 at 20:42