UITableView 单元格上的 Peek 和 Pop 因 UISearchController 而失败
Peek and Pop on UITableView cells fails with UISearchController
Peek and Pop 正在使用 UISearchController
。但是,一旦您开始使用 updateSearchResults
.
搜索 table,Peek 和 Pop 就会停止工作
我扩展了 Apple 的 Table Search with UISearchController demo 以支持 Peek 和 Pop 作为示例:
问题是当我开始搜索 table 时,Peek 和 Pop 不再起作用。它只是 select 突出显示它:
我对 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)
}
}
搜索上下文控制器是否干扰了 peek 和 pop(甚至可能是键盘)?当 table 最初是所有数据时,我可以让它工作,但一旦我开始使用搜索,它就不会工作。我附上了 working sample here 如果你想 运行 它并查看问题。
首先,在您的 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 在所有三种状态下都有效。
Peek and Pop 正在使用 UISearchController
。但是,一旦您开始使用 updateSearchResults
.
我扩展了 Apple 的 Table Search with UISearchController demo 以支持 Peek 和 Pop 作为示例:
问题是当我开始搜索 table 时,Peek 和 Pop 不再起作用。它只是 select 突出显示它:
我对 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)
}
}
搜索上下文控制器是否干扰了 peek 和 pop(甚至可能是键盘)?当 table 最初是所有数据时,我可以让它工作,但一旦我开始使用搜索,它就不会工作。我附上了 working sample here 如果你想 运行 它并查看问题。
首先,在您的 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 在所有三种状态下都有效。