UITableView 单元格上的 Peek 和 Pop 使用 UISearchController 失败

Posted

技术标签:

【中文标题】UITableView 单元格上的 Peek 和 Pop 使用 UISearchController 失败【英文标题】:Peek and Pop on UITableView cells fails with UISearchController 【发布时间】:2017-02-13 04:36:28 【问题描述】:

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

我已经扩展了 Apple 的 Table Search with UISearchController demo 以支持 Peek 和 Pop 作为示例:

问题是当我开始搜索表格时,Peek and Pop 不再起作用。它只是选择突出显示它:

我对@9​​87654329@ 所做的更新是:

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)
    

搜索上下文控制器是否干扰了 peek and pop(甚至可能是键盘)?当表格最初是所有数据时,我可以让它工作,但一旦我开始使用搜索,它就不会工作。如果您想运行它并查看问题,我附上了working sample here。

【问题讨论】:

你有什么问题? 我用截图和更多细节更新了这个问题,谢谢 :) 我可以确认不是键盘阻挡了窥视和弹出。我驳回了它,问题仍然存在。 抱歉,我没有 3d touch iPhone,并且在模拟器中没有 xcode 提供的功能。我想帮助你,但很遗憾我不能为你感到抱歉 【参考方案1】:

首先,在您的 MainTableViewController.viewDidLoad() 中,您还需要注册您的 resultsTableController.tableView,因为这是一个单独的视图,将接收 peek/pop 信息:

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),

在您的原始代码中,它使用MainTableViewController 上的tableView 属性而不是tableView,即sourceView 进行交互。

现在,无论您在搜索还是不搜索,这都可以使用。但是,当您输入搜索但尚未输入任何搜索文本时,UISearchController 处于活动状态,但 UITableView 是来自 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 出现时,我们注销MainTableViewController 并注册搜索控制器。当它被解除时,我们做相反的事情。

通过这些更改,peek 和 pop 可以在所有三种状态下工作。

【讨论】:

@TruMan1,我的回答有帮助吗? 只要您有一个单独的 searchResultsController,它就可以正常工作。但是,如果您使用 table view controller 本身来显示搜索结果,则 searchController.searchResultsController 为 nil (根据 Apples 文档:“searchResultsController:显示搜索结果的视图控制器。如果要显示搜索结果,请指定 nil显示可搜索内容的同一视图控制器。” 我无法让 Peek 和 Pop 与 searchController 一起工作。 searchController.registerForPreviewing(...) 为我完成了这项工作,我只是在 viewDidLoad 中设置了它。我花了几个小时尝试不同的事情,但是使用 self.registerForPreviewing(...) 它没有调用已实现的委托方法。谢谢。 @dkrdennis 的建议对我有用,但是,在持有搜索控制器的视图控制器上调用 registerForPreviewing(with:sourceView:) 后,我不得不在搜索控制器上调用它。 经过进一步测试,我想稍微改变一下我上面的评论。我发现当搜索控制器在 UISearchControllerDelegate 的willPresentSearchController(_:) 中注册预览时效果最好。同时,应该取消注册视图控制器。在willDismissSearchController(_:) 中反之亦然。

以上是关于UITableView 单元格上的 Peek 和 Pop 使用 UISearchController 失败的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 单元格未显示放置在自定义单元格上的 UITableView(KPDropDown)

为啥我的 UITableView 单元格上的这个按钮会重新绘制自己?

处理 UITableView 单元格上的平移手势

ios UITableview 单个单元格上的多个选择选项?

指定表格页脚时,最后一个单元格上的uitableview分隔符丢失

UItableview 在自定义单元格上使用带有提示的警报视图重新加载数据的问题