UITableView单元格上的Peek和Pop因UISearchController而失败

时间:2017-02-13 04:36:29

标签: ios swift uitableview uisearchcontroller peek-pop

Peek和Pop正在使用UISearchController。但是,一旦您使用updateSearchResults开始搜索表格,Peek和Pop就会停止工作。

我将Apple的Table Search with UISearchController demo扩展为支持Peek和Pop的例子: enter image description here

问题是,当我开始搜索表时,Peek和Pop不再起作用了。它只是选择亮点: enter image description here

我所做的更新是MainTableViewController

class MainTableViewController: BaseTableViewController, UISearchBarDelegate, UISearchControllerDelegate, UISearchResultsUpdating {
    override func viewDidLoad() {
        super.viewDidLoad()
        ...
        if traitCollection.forceTouchCapability == .available {
            registerForPreviewing(with: self, sourceView: tableView)
        }
    }
}

extension MainTableViewController: UIViewControllerPreviewingDelegate {

    func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
        guard let indexPath = tableView?.indexPathForRow(at: location),
            let cell = tableView?.cellForRow(at: indexPath),
            let controller = storyboard?.instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController
                else { return nil }

        previewingContext.sourceRect = cell.frame

        controller.product = products[0]

        return controller
    }

    func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
        guard let controller = viewControllerToCommit as? DetailViewController else { return }
        controller.product = products[0]
        show(controller, sender: self)
    }
}

搜索上下文控制器是否会干扰窥视和弹出(甚至可能是键盘)?当表最初所有数据时,我可以让它工作,但它并没有一次我开始使用搜索。如果您想要运行它并查看问题,我附加了working sample here

1 个答案:

答案 0 :(得分:18)

首先,在您的MainTableViewController.viewDidLoad()中,您还需要注册resultsTableController.tableView,因为这是一个单独的视图,可以接收查看/弹出信息:

if traitCollection.forceTouchCapability == .available {
    previewingContext = registerForPreviewing(with: self, sourceView: tableView)
    if let resultVC = searchController.searchResultsController as? ResultsTableController {
        resultVC.registerForPreviewing(with: self, sourceView: resultVC.tableView)
    }
}

在测试此解决方案时,我注意到一个奇怪的问题,即结果集中的第一行不可查看,结果集中的空行可以查看。那么,previewingContext(_:viewControllerForLocation:)中的第二个修复:

func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
    guard let tableView = previewingContext.sourceView as? UITableView,
        let indexPath = tableView.indexPathForRow(at: location),

在原始代码中,它使用tableView上的MainTableViewController属性,而不是tableView的{​​{1}}进行交互。

现在,这在您搜索时有效,而在您不在时。但是,当您输入搜索但尚未输入任何搜索文本时,sourceView处于有效状态,但UISearchController是来自UITableView的{​​{1}},您无法两次将视图注册为源视图。所以,我们还有一些工作要做:

MainTableViewController

基本上,当出现// 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) } } 时,我们取消注册UISearchController并注册搜索控制器。当它被解雇时,我们会反过来。

通过这些变化,可以在所有三个州中查看和弹出工作。