Reputation: 162
I am looking to implement a search such that when the user presses a search result, the relevant UIViewController
is pushed onto the search result itself, allowing the user to press back to view the search result again.
I have tried simply pushing the ViewController onto the presenting ViewController's UINavigationController
. This results in the UIViewController
appearing behind the search result (it can be seen when canceling the search result).
I have also tried subclassing UINavigationController
and making it conform to UISearchResultsUpdating
, proxying the updates to the UIViewController
. This results in almost the correct behavior, but the search bar remains with the navigation bar when a view controller is being pushed onto the UINavigationController
, as can be seen in the image below.
I could simply do some hacky code to hide/show the search bar depending on the state of the UINavigationController
, but it seems like there must exist a cleaner way of accomplishing this.
Apple has themselves done this in their Notes app, if you do a search and press a result, you are brought to the relevant note, pressing back takes you back to the search result. So I am wondering how to replicate this behavior correctly.
Upvotes: 0
Views: 95
Reputation: 162
I later solved this the hacky way by making the UIViewController
that is responsible for displaying the search result conform to the UINavigationControllerDelegate
protocol (in addition to UISearchResultsUpdating
). The updateSearchResultsForSearchController(searchController: UISearchController)
method then catches and stores a reference to the UISearchController
that is passed as a parameter. Then this juggling with view-logic in the UINavigationControllerDelegate
code makes everything work and look as expected:
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
if viewController == self {
searchController.searchBar.hidden = false
searchController.searchBar.becomeFirstResponder()
} else {
searchController.searchBar.hidden = true
searchController.searchBar.resignFirstResponder()
}
}
Lastly, as explained in the third paragraph above, I made a subclass of UINavigationController
which is assigned as the search results controller, and which delegates navigation events and UISearchResultsUpdating
events to the UIViewController
.
This certainly works as intended and I not experienced any bugs with this so far. Will post an update if I find a cleaner solution next time I look over this code (might be easier in iOS 9).
Upvotes: 1