当searchController处于激活状态时,3D Touch无法使用。

6
我已经在uicollectionview中实现了3D Touch,它工作得很好。但是当uisearchController处于活动状态时,3D Touch就不起作用了。uisearchController使用collectionView来显示结果。 这个帖子中也有同样的问题。 有人遇到过类似的问题吗?谢谢。 我已经找到了解决方案: 扩展MyViewController:UISearchControllerDelegate {
func didPresentSearchController(_ searchController: UISearchController) {
    if let context = previewingContext {
    unregisterForPreviewing(withContext: context)
    previewingContext = searchController.registerForPreviewing(with: self, sourceView: self.myCollectionView)
    }
}

func didDismissSearchController(_ searchController: UISearchController) {
    if let context = previewingContext {
        searchController.unregisterForPreviewing(withContext: context)
        previewingContext = registerForPreviewing(with: self, sourceView: self.myCollectionView)
    }
}

}


我找到了以下解决方案: - user8771003
1个回答

2
需要创建一个实例变量来存储从registerForPreviewing(with: sourceView:)返回的预览上下文,它需要为视图控制器创建。当标准控制器被显示时,它必须作为self的方法调用,但当搜索控制器被显示时,它必须作为(self.)searchController的方法调用。这就是由@user8771003提供的扩展所做的。还需要设置UISearchController的委托。
我为UITableViewController创建了一些Swift 4.2、iOS 12兼容的代码,以便更容易理解,尽管对于任何其他UIView来说,它都非常相似。我使用了self来增加简洁性。
import UIKit

/// View controller for table view
class TableViewController: UITableViewController {

    //
    // MARK: - Properties
    //

    /// Data to display in table view
    var data = [String]()

    /// Controller for table view search bar
    let searchController = UISearchController(searchResultsController: nil)

    /// The 3D touch peek and pop preview context for switching between table view and search controller results
    var previewingContext: UIViewControllerPreviewing?

    //
    // MARK: - Life cycle methods
    //

    /// Sets up the table view
    override func viewDidLoad() {
        super.viewDidLoad()

        configureSearchBar()
        setupPeekAndPop()
        refreshData()

        self.tableView.reloadData()
    }

    /// Configures behaviour for search bar on older devices
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        if #available(iOS 11.0, *) {

        } else {
            self.searchController.dismiss(animated: false, completion: nil)
        }
    }

    //
    // MARK: - Table view data source
    //

    // ...

    //
    // MARK: - Navigation
    //

    // ...

    //
    // MARK: - Private methods
    //

    /// Reloads the data for the table view
    /// - Parameter query: Search query to filter the data
    private func refreshData(query: String = "") {
        // ...
    }

    /// Configures the search bar
    private func configureSearchBar() {
        self.searchController.searchResultsUpdater = self
        self.searchController.searchBar.placeholder = "Search"
        self.searchController.delegate = self

        if #available(iOS 11.0, *) {
            self.searchController.obscuresBackgroundDuringPresentation = false
            self.navigationItem.searchController = self.searchController
            self.definesPresentationContext = true
        } else {
            self.searchController.dimsBackgroundDuringPresentation = false
            self.searchController.hidesNavigationBarDuringPresentation = false
            self.tableView.tableHeaderView = self.searchController.searchBar
        }
    }

}

// MARK: - Search results extension

/// Manages the extension for the `UISearchResultsUpdating` protocol to implement the search bar
extension TableViewController: UISearchResultsUpdating {

    /// Updates the table view data when the search query is updated
    func updateSearchResults(for searchController: UISearchController) {
        let query = self.searchController.searchBar.text!
        refreshData(query: query)
        self.tableView.reloadData()
    }

}

// MARK: - Peek and pop extension

/// Managess the extension for the `UIViewControllerPreviewingDelegate` protocol to implement peek and pop
extension TableViewController: UIViewControllerPreviewingDelegate {

    //
    // MARK: - Public methods
    //

    /// Manages the previwing of the destination view controller for peeking
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
        guard let indexPath = self.tableView?.indexPathForRow(at: location) else { return nil }
        guard let cell = self.tableView?.cellForRow(at: indexPath) else { return nil }

        guard let detailVC = storyboard?.instantiateViewController(withIdentifier: "DestinationStoryboardIdentifier") as? DestinationViewController else { return nil }

        let item = self.data[indexPath.row]
        detailVC.item = item
        detailVC.preferredContentSize = CGSize(width: 0.0, height: 0.0)
        previewingContext.sourceRect = cell.frame

        return detailVC
    }

    /// Manages the showing of the destionation view controller for popping
    func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
        show(viewControllerToCommit, sender: self)
    }

    //
    // MARK: - Private methods
    //

    /// Registers for peek and pop if device is 3D touch enabled
    /// - Note: Should be called in `viewDidLoad()`
    private func setupPeekAndPop() {
        if traitCollection.forceTouchCapability == .available {
            self.previewingContext = self.registerForPreviewing(with: self, sourceView: view)
        }
    }

}

// MARK: - Peek and pop on search results

/// Manages the extension for the `UISearchControllerDelegate` for implementing peek and pop on search results
extension TableViewController: UISearchControllerDelegate {

    /// Switches previewing context for peek and pop to search controller results
    func didPresentSearchController(_ searchController: UISearchController) {
        if let context = self.previewingContext {
            self.unregisterForPreviewing(withContext: context)
            self.previewingContext = self.searchController.registerForPreviewing(with: self, sourceView: view)
        }
    }

    /// Switches previewing context for peek and pop to table view
    func didDismissSearchController(_ searchController: UISearchController) {
        if let context = self.previewingContext {
            self.searchController.unregisterForPreviewing(withContext: context)
            self.previewingContext = self.registerForPreviewing(with: self, sourceView: view)
        }
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接