如何最初在导航栏中显示搜索栏,但当用户向上滚动时仍然隐藏它?

REl*_*ott 5 uinavigationbar uisearchbar swift

我正在构建一个基本的 ViewController,其中包含具有多个部分的 CollectionViewController。我希望在 NavigationBar 中包含一个 UISearchBar,但 Swift 似乎只允许两种行为选项:最初隐藏搜索栏,然后在用户向下滚动时显示它,或者始终显示搜索栏。

我希望搜索栏的功能就像在消息应用程序中一样,用户无需滚动即可显示搜索栏,然后在用户向下滚动页面时隐藏。我确信有一个简单的解决方案,但我对 iOS 开发相当陌生,并且无法找到任何以前提出的问题。

搜索栏始终存在的情况的示例:

在此输入图像描述

用户必须向下滚动才能显示搜索栏的示例:

在此输入图像描述

控制器和搜索栏的初始化:

let searchController = UISearchController(searchResultsController: nil)

let searchBar: UISearchBar = {
    let search = UISearchBar()
    search.placeholder = "Search"
    search.translatesAutoresizingMaskIntoConstraints = false
    search.sizeToFit()
    search.barStyle = .default
    return search
}()

// Truncated...

// Called from viewDidLoad()
func configureSearchBar() {
    searchController.searchResultsUpdater = self
    searchController.obscuresBackgroundDuringPresentation = false
    searchController.searchBar.placeholder = "Search"
    searchController.searchBar.translatesAutoresizingMaskIntoConstraints = false
    searchController.isActive = true
    definesPresentationContext = true

    navigationItem.title = "Test Title"
    navigationItem.searchController = searchController
    navigationItem.hidesSearchBarWhenScrolling = false
}
Run Code Online (Sandbox Code Playgroud)

我知道这段代码不会产生预期的行为,但是我可以进行简单的修改以使其正常运行吗?

max*_*lxb 0

我找到了一种最初显示 UISearchbar 的方法。在这一点上,我不太确定这是否是苹果的意图,或者这是否只是为了让一个简单的行为发挥作用而进行的另一种黑客行为。

设置viewDidLoad通话后UISearchController

present(searchController, animated: true)
Run Code Online (Sandbox Code Playgroud)

然后,这将动画并扩展导航栏并显示搜索栏。编辑完栏中的文本后,不要忘记再次关闭它。即使您最初隐藏了搜索栏,也需要执行此操作,因为如果不这样做,它将被保留,最终会导致泄漏。

编辑: 为了回答你的其余问题,我提供了一些演示代码来理解这个想法:

您可以观察 contentOffset 并在其具有特定值时将其关闭:

observable = self.viewDictionary.tableView.observe(\.contentOffset) { [unowned self] value in
        guard let offset = value else { return }
        if offset.y > 30 {
            self.navigationItem.searchController?.dismiss(animated: true)
        }
    }
Run Code Online (Sandbox Code Playgroud)

观察者代码使用此处找到并解释的简单扩展,但使用标准库版本也可以。