【问题标题】:How to initially show SearchBar in the NavigationBar but still have it hide as the user scrolls up?如何最初在导航栏中显示搜索栏,但在用户向上滚动时仍将其隐藏?
【发布时间】:2019-04-25 05:30:28
【问题描述】:

我正在构建一个基本的 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
}

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

【问题讨论】:

  • "Messages 应用程序,无需用户滚动即可显示,",当您启动消息应用程序时,默认情况下它不会显示搜索字段并且仅在您位于顶部时向上滚动时显示
  • 好吧,你为什么不把你的 Custom CollectionView 的第一个单元格设置为搜索栏,这样每当 collectionView 加载时,搜索栏总是会出现在顶部,当您滚动时,它将被隐藏,然后当您再次滚动到顶部时,它将可见。但这似乎不是导航栏的一部分

标签: swift uinavigationbar uisearchbar


【解决方案1】:

我找到了一种最初显示 UISearchbar 的方法。在这一点上,我不确定这是 Apple 的意图,还是只是为了让一个简单的行为起作用。

viewDidLoad 设置您的UISearchController 呼叫后:

present(searchController, animated: true)

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

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

你可以观察 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,但使用标准库版本也可以。

【讨论】:

    【解决方案2】:

    在 viewDidLoad() 中设置hidesSearchBarWhenScrolling = true

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-07
      相关资源
      最近更新 更多