如何在没有底层 UIScrollView 的情况下在 UINavigationItem 上显示 UISearchController?

How do I display a UISearchController on a UINavigationItem without an underlying UIScrollView?

也许这是不可能的,但我一直认为您可以将 UISearchController 实例扔到任何旧视图控制器的 navigationItem 上并获得搜索栏。在我看来,无论我尝试什么,我都无法让它发挥作用。这让我觉得这种行为是硬编码的,只有当视图控制器的 view 属性 是 UIScrollView.

的子类时才有效

我希望这只是一个转移注意力的问题。如果我遗漏了一些明显的东西,请帮忙!真气人。

这是我所做的:

import UIKit.UIViewController

class MainViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        navigationItem.hidesSearchBarWhenScrolling = false

        navigationItem.searchController = {
            let searchController = UISearchController()
            searchController.hidesNavigationBarDuringPresentation = false
            searchController.dimsBackgroundDuringPresentation = false
            searchController.obscuresBackgroundDuringPresentation = false
            return searchController
        }()
    }
}

屏幕上从未出现过搜索栏。它看起来就像一个普通的旧导航栏。

UISearchController 初始值设定项应 let searchController = UISearchController(searchResultsController: nil) 或用单独的控制器替换 nil 以显示搜索结果。

如果您的 viewController 在 UINavigationController 堆栈中,那么上面的代码应该可以工作(使用更正的初始值设定项)。否则,您将需要创建一个 UINavigationBar 并将其添加到视图中。然后将 searchController.searchBar 添加到 navigationItem.titleView

    let navigationBar = UINavigationBar()
    view.addSubview(navigationBar)
    navigationBar.barTintColor = UIColor.gray
    navigationBar.translatesAutoresizingMaskIntoConstraints = false
    navigationBar.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    navigationBar.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
    navigationBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
    navigationBar.delegate = self

    navigationBar.items = [navigationItem]

    navigationItem.searchController = {
        let searchController = UISearchController(searchResultsController: nil)
        searchController.hidesNavigationBarDuringPresentation = false
        searchController.dimsBackgroundDuringPresentation = false
        searchController.obscuresBackgroundDuringPresentation = false
        return searchController
    }()

    navigationItem.titleView = navigationItem.searchController?.searchBar