On Feb 7, 2016, at 9:08 AM, Chris Fleizach <
email@hidden> wrote:
On Feb 3, 2016, at 7:25 AM, Boris Dušek <
email@hidden> wrote:
2. In case it is a bug: Is there a workaround other than using a separate non-nil searchResultsController (e.g. I tried setting accessibilityElementsHidden=false on the original vc’s view, but to no avail).
Another thought occurred to me that perhaps you can implement accessibilityElements on a parent view and return either the view from the search controller or the view from the table view depending on which is active. Might work and shouldn’t be too hard (although if you have story boards everywhere, that might not be true)
seems your suggestion worked – thank you very much for it (and even more so for providing in on a Saturday) – with one addition. Since the code is trivial and more precise than words, I will just paste it here:
extension ResultsVC: UISearchControllerDelegate {
func didPresentSearchController(searchController: UISearchController) {
searchController.view.accessibilityElements = [searchController.searchBar, tableView]
searchController.view.accessibilityViewIsModal = false
}
func willDismissSearchController(searchController: UISearchController) {
searchController.view.accessibilityViewIsModal = true
searchController.view.accessibilityElements = nil
}
}
(Of course, one has to set the ResultsVC as the delegate of the searchController for these methods to be called.)
It works both in my simple repro code-only project, as well as in a real project using storyboards. The addition is "accessibilityViewIsModal=true” on the search controller view and it is “only” needed to make touch-exploration work (without it, the results can be visited by flicking gestures, but not by touching the cells directly). Note that this works only when used in didPresent*/willDismiss* delegate methods. If the same is tried in willPresent*/didDismiss* delegate methods, it has no effect.
Both searchController.view (_UISearchControllerView), and its parent (UITransitionView), have accessibilityViewIsModal = true by default from UIKit, but it is the UITransitionView that is a sibling of the UITableView, so according to the docs on accessibilityViewIsModal, setting searchController.view.accessibilityViewIsModal = false should have no effect (the view has no sibling) and it should be setting the same on the UITransitionView, i.e. searchController.view.superview, that should do the trick of making the table view available.
When I tried setting just accessibilityViewIsModal=true on the searchController.view and its parent, without modifying the searchController.view ’s accessibilityElements, I too achieved that the results table was visible to VoiceOver, but in this case the table cells were ordered before anything else, i.e. even *before* the search bar and field.
So it turns out for optimal experience, one has to use both the accessibilityElements and accessibilityViewIsModal on the searchController.view to achieve a workaround for the bug.
So the way with the above code, things work just like with non-nil searchResultsController passed to UISearchController init, and even a bit better: in a situation where no search string is entered into the search field, the visible original vc is usable with VoiceOver (just like for sighted users), unlike in a case where a non-nil searchResultsController is used.
Also regarding Switch Control, with the original code with nil searchResultsController, Switch Control does not visit the table cells at all; with the above workaround, it does.
few things necessary to watch out when doing this:
- this expects that searchController.searchBar and tableView are really the only presented elements in the search view during searching; if the UI is somehow more complex, one has to make sure nothing is missing the accessibilityElements
- things could start working a little bit differently in next iOS release, so it is better to watch out that VoiceOver interprets the accessibility hierarchy the same way (and that UIKit implements accessibility the same way) by testing on a new iOS release (but hopefully after I report the rdar, the bug will be fixed in iOS 10 and the above workaround will not be necessary - one can always hope :-) )
- so given the above 2 points, it might be a little bit more reliable to go through the way of non-nil searchResultsController; thought that still does not solve the case of the search controller being active with empty search string (unlike with the workaround above)
I will report the rdar at the beginning of the next week and post the number here.
Thanks again,
Boris
—