如何在 iOS 13 上最初隐藏导航控制器中的搜索栏?

Posted

技术标签:

【中文标题】如何在 iOS 13 上最初隐藏导航控制器中的搜索栏?【英文标题】:How to initally hide searchbar in Navigation controller on iOS 13? 【发布时间】:2019-08-20 21:08:47 【问题描述】:

ios 13 中,行为发生了变化,因此默认情况下,当导航控制器出现时,搜索栏是可见的(当 UISearchController 分配给 navigationItem.searchController 时)。某些系统应用程序出现时隐藏了搜索栏(您需要向下滑动才能显示),但我没有看到任何允许这样做的特定属性。如何实现这一点 - 也许有一些属性或方法可以做到这一点?

【问题讨论】:

导航控制器默认没有搜索栏,所以请更新您的问题,详细说明您正在做什么以获取搜索栏。 有不同的解决方案,因此您必须清楚自己在做什么,这一点很重要。您的编辑还不够详细。 @rmaddy 作为某些人(可能是您)投反对票,请回答您所缺少的内容。您是否尝试通过上述描述重现问题。我可以,而且我看不到搜索栏控制器的实现会如何影响这一点,因为即使是最简单的控制器也是如此。 这个问题对我来说似乎很清楚。分配了搜索控制器(因此带有搜索栏)的导航项在 iOS 13 中的行为有所不同 - 它们在加载时可见。显而易见的想法(设置表格的内容偏移量,或以编程方式将表格滚动到第一行)不起作用。 【参考方案1】:

通过实验,我发现如果您延迟将搜索控制器分配给导航项,直到viewWillLayoutSubviewsviewDidLayoutSubviews,搜索控制器会根据需要开始隐藏。但是,如果您在 iOS 12 或更早版本上执行此操作,则向下滚动时不会显示搜索控制器。

我最终做了以下混乱的版本检查,这对我有用:

override func viewDidLoad() 
    super.viewDidLoad()

    searchController = /* make search controller... */

    if #available(iOS 13, *) 
        // Attaching the search controller at this time on iOS 13 results in the
        // search bar being initially visible, so assign it later
    
    else 
        navigationItem.searchController = searchController
    


override func viewWillLayoutSubviews() 
    super.viewWillLayoutSubviews()
    navigationItem.searchController = searchController


【讨论】:

这听起来很有希望,我已经投了赞成票,但至少对我来说它没有任何效果,所以它可能只在某些情况下有效。 @IvanIčin :( 原始帖子是我遇到的确切问题,这为我解决了问题。谢谢@bunnyhero 我有一个标签栏控制器(初始 vc)-> 根 vc 是带有 UIViewController 的导航控制器,它有一个 UITableView 并且我无法在加载期间隐藏搜索栏..试过一切:(@bunnyhero 如果在viewWillLayoutSubviewsviewDidLayoutSubviews 中对您不起作用,请尝试在viewDidAppear 中进行。这对我有用!【参考方案2】:

要从隐藏的searchBar 开始,只需设置navigationItem.searchController 属性您的表格视图(或集合视图)已填充数据。 p>

【讨论】:

这些答案都不适合我。使用这种方法,它要么根本不存在,直到我切换到不同的视图然后再返回,要么它已经存在。它的接缝有点随意,有一次它刚刚弹出,一点也不光滑。我觉得他们不想隐藏它。在本教程中,我正在关注他说你“可能”必须下拉才能看到它,但是当我运行他的示例时,它已经在那里了。 raywenderlich.com/…必须依赖iOS版本【参考方案3】:

受bunnyhero's answer 的启发,我将负责在navigationItem 中设置UISearchController 的代码放在viewDidAppear 方法中。似乎每次都在 iOS 14/15 上为我工作

override func viewDidAppear(_ animated: Bool) 
    super.viewDidAppear(animated)
    if navigationItem.searchController == nil 
        navigationItem.searchController = searchController
    

编辑:我过于乐观了。在 iOS 15.2 上,这种方法对我不起作用。我所做的修复它是在重新加载我的表/集合视图后移动代码。

【讨论】:

即使在重新加载 collectionView 后对 searchBar 设置进行排序时,我也无法获得所需的行为。我终于通过使用 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) 延迟 searchBar 设置来让它工作。【参考方案4】:

我觉得这行得通:

self.searchController.searchBar.hidden = YES;

您需要在适当的时候取消隐藏。

【讨论】:

我想在某种程度上它会起作用。但我并不认为它就像在邮件应用程序中那样向下滚动时栏会显示动画【参考方案5】:

我设法通过在navigationBar 上设置isTransculent false 并在UITableViewUICollectionView 上获得初始数据来完成这项工作。如果您最初有 0 个单元格并在一段时间后触发 reloadData(可能是网络调用),则 SearchBar 最初是可见的。所以最初有一个虚拟单元或类似的东西,然后再加载数据,如果你是这样的话。

navigationController?.navigationBar.isTranslucent = false

【讨论】:

【参考方案6】:

应该在tableView 获取框架后设置searchController

override func scrollViewDidScroll(_ scrollView: UIScrollView) 
    super.scrollViewDidScroll(scrollView)

    if !scrollView.frame.isEmpty, navigationItem.searchController == nil 
        navigationItem.searchController = searchController
    

【讨论】:

【参考方案7】:

这对我有用。我有一个 UISegmentedControl 在过滤器更改时重新加载 tableView。

使用 FRC:

guard let count = try? fetchedResultsController.managedObjectContext.count(for: request) else  return 

在 tableView.reloadData() 之后调用

navigationItem.searchController = count > 20 ? searchController : nil

【讨论】:

【参考方案8】:

Swift 5.2 和 iOS 13.3.1:-

试试这样。效果很好

        navigationItem.hidesSearchBarWhenScrolling = false

【讨论】:

你试过了吗?根据文档,它不是这样工作的:developer.apple.com/documentation/uikit/uinavigationitem/…

以上是关于如何在 iOS 13 上最初隐藏导航控制器中的搜索栏?的主要内容,如果未能解决你的问题,请参考以下文章

iOS:在导航栏中显示搜索栏时隐藏范围栏

如何隐藏大标题 iOS 11 搜索控制器

向导航栏添加渐变将隐藏 iOS 13.0 + 中的栏按钮项目

在 iOS13 + xcode 11 中隐藏导航栏

搜索显示控制器如何隐藏导航栏?

屏幕键盘出现时iOS隐藏导航栏