Peek and Pop is working with a UISearchController
. However, Peek and Pop stops working once you start searching the table using updateSearchResults
.
First, in your MainTableViewController.viewDidLoad()
you need to also register your resultsTableController.tableView
, since that is a separate view that will receive peek/pop information:
if traitCollection.forceTouchCapability == .available {
previewingContext = registerForPreviewing(with: self, sourceView: tableView)
if let resultVC = searchController.searchResultsController as? ResultsTableController {
resultVC.registerForPreviewing(with: self, sourceView: resultVC.tableView)
}
}
When testing this solution, I noticed a strange problem, that the first row in the result set wasn't peekable, and blank rows in the result set WERE peekable. So, the second fix in previewingContext(_:viewControllerForLocation:)
:
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
guard let tableView = previewingContext.sourceView as? UITableView,
let indexPath = tableView.indexPathForRow(at: location),
In your original code, it was using the tableView
property on the MainTableViewController
instead of the tableView
that was the sourceView
for the interaction.
Now, this works when you're searching, and when you're not. However, when you've entered the search, but haven't entered any search text yet, the UISearchController
is active, but the UITableView
is the one from MainTableViewController
, and you cannot register a view as a source view twice. So, we have a little more work to do:
// local property to store the result from registerForPreviewing(with:sourceView:)
var previewingContext: UIViewControllerPreviewing?
func didPresentSearchController(_ searchController: UISearchController) {
if let context = previewingContext {
unregisterForPreviewing(withContext: context)
previewingContext = searchController.registerForPreviewing(with: self, sourceView: tableView)
}
}
func didDismissSearchController(_ searchController: UISearchController) {
if let context = previewingContext {
searchController.unregisterForPreviewing(withContext: context)
previewingContext = registerForPreviewing(with: self, sourceView: tableView)
}
}
Basically, when the UISearchController
is presented, we unregister MainTableViewController
and register the search controller. When it is dismissed, we do the reverse.
With these changes, peek and pop work in all three states.