Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hide UITableViewCell from VoiceOver

I have a static UITableView with various cells in it. I need to hide/show some of those cells, so I've implemented heightForRowAtIndexPath and return 0 when appropriate in order to hide the right cells. This works great for sighted users, but for those who use VoiceOver those elements are still highlighted and accessible when they should not be. How can I ensure those UITableViewCells are no longer accessible when I change their height to 0?

I've tried setting the cell to not be an accessible element as well as setting the elements to be hidden but this has no effect on it. The cell has not been subclassed - it's just a UITableViewCell. I have not set anything in regards to accessibility on the cell nor the cell's contents (textLabel, detailTextLabel).

Doesn't do the trick:

self.cellToHide.isAccessibilityElement = NO;
self.cellToHide.accessibilityElementsHidden = YES;
like image 750
Jordan H Avatar asked Mar 27 '15 21:03

Jordan H


1 Answers

Update Cell VoiceOver Elements By Reloading Cell(s)

After reading about a UITableView taking control over Accessibility elements and observing apps that have similar features, I figured that a TableView must update its Accessibility information upon loading or reloading a cell. I tried forcing the cell to reload after changing its Accessibility properties and that solved the problem. VoiceOver information was updated.

The following is an example of code that runs when the cell in question is tapped. Alternatively, it could run when some other event requires that VoiceOver elements are updated.

// Make changes to accessibility properties such as
cell.isAccessibilityElement = false
cell.accessibilityElementsHidden = true

// reloadRows() allows VoiceOver to update its element list for the related cell(s)
// "indexPath" is for the desired row
// reloadRows() expects an array of IndexPaths so an array of one is created inline
tableView.reloadRows(at: [indexPath], with: .automatic)

// Calling UIAccessibilityPostNotification() is not necessary to realize the VoiceOver changes in the TableViewCell

 

Background

I wrestled with this problem for a while before finding a solution. In my case the TableView cells are created in code. There are no storyboards or nibs involved. However, this solution should work regardless of how the TableView was constructed.

I have custom, subclassed TableView cells with view hierarchies built in code and added as a subview of the UITableViewCell's contentView. I assumed I could modify the isAccessibilityElement and/or accessibilityElementsHidden properties of various subviews and call UIAccessibilityPostNotification() to realize the VoiceOver changes as I have done outside of TableView's. These changes were not recognized by VoiceOver, only the accessibility state the cell was in when it was loaded was recognized.

For the cell I wrestled with, the height dynamically changes to accommodate a DatePicker that is shown and hidden on cell tap. I only want the DatePicker visible to VoiceOver when it is visible on the screen. I try to avoid reloading the TableView, Sections or Rows to make dynamic changes if at all possible. If I have to reload, I try to make it as isolated as possible (reload one cell or one section not the whole TableView). In this case I did not need to reload anything to make the cell expand to reveal the DatePicker so it did not occur to me try reloading the cell for Accessibility updates.

Related Information: UIAccessibility API Reference on Apple's web site

like image 52
Mobile Dan Avatar answered Oct 07 '22 03:10

Mobile Dan