如何最初在NavigationBar中显示SearchBar但在用户向上滚动时仍将其隐藏?

时间:2019-04-25 05:30:28

标签: swift uinavigationbar uisearchbar

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

我希望搜索栏像在Messages应用程序中一样发挥作用,它在显示时无需用户滚动,然后在用户向下滚动页面时隐藏。我敢肯定有一个简单的解决方案,但是我对iOS开发是相当陌生的,因此无法找到任何以前问过的问题。

始终显示搜索栏的外观示例:

enter image description here

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

enter image description here

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

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
}

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

2 个答案:

答案 0 :(得分:1)

在viewDidLoad()中设置hidesSearchBarWhenScrolling = true

将滚动视图contentOffset设置为viewWillAppear()中searchBar高度的倒数。

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    let offset = -(searchController.searchBar.frame.height)
    tableView.setContentOffset(CGPoint(x: 0, y: offset), animated: false)
}

答案 1 :(得分:0)

我找到了一种最初显示UISearchbar的方法。在这一点上,我真的不确定这是否是Apple打算的,还是仅仅是一种黑客来使简单行为起作用。

在设置viewDidLoad通话后在UISearchController

present(searchController, animated: true)

然后将设置动画并扩展NavigationBar并显示搜索栏。编辑完栏中的文本后,请不要忘记再次将其关闭。即使您最初是隐藏搜索栏,也需要执行此操作,因为如果不隐藏搜索栏,则会导致泄漏。

编辑: 为了回答您剩下的问题,我提供了一些演示代码来传达您的想法:

您可以观察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)
        }
    }

观察者代码使用发现并说明了here的简单扩展名,但是使用标准库版本也可以。