当UISearchController处于活动状态时,iOS 9中的搜索栏从表头视图中消失

55

结构:

View1(点击一个按钮) -> 模态呈现(MyModalView: UITableViewController)

MyModalView包含嵌入的UISearchController。UISearchController的搜索栏位于MyModalView.tableView.tableHeaderView中。

自iOS 8.0以来一直正常工作。但在iOS 9上,当UISearchController处于活动状态时,搜索栏会消失。请查看下面的图片

模态视图:modal view

iOS 8上的活动UISearchController:search bar in iOS 8

iOS 9上的活动UISearchController:search bar in iOS 9

非常标准的代码:

override func viewDidLoad() {
    super.viewDidLoad()

    // Dynamically create a search controller using anonymous function
    self.resultSearchController = ({
        let controller = UISearchController(searchResultsController: nil)
        controller.searchResultsUpdater = self
        controller.dimsBackgroundDuringPresentation = false

        controller.searchBar.sizeToFit()
        controller.searchBar.delegate = self

        self.tableView.tableHeaderView = controller.searchBar

        return controller
    })()

    // Auto sizing row & cell height
    self.tableView.estimatedRowHeight = 130
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.definesPresentationContext = true

    // No footer for better presentation
    self.tableView.tableFooterView = UIView.init(frame: CGRectZero)
}

这个问题也发生在 iOS 9.1 beta 中...

有任何想法/指针将不胜感激

谢谢。


对我来说,这只发生在设备上(而不是模拟器中)。 - Ian Dundas
嗨@IanDundas,我在下面发布了我的答案,你想试试看它是否能解决你的问题吗? - David Trang
是的,实际上@Shwethascar的修复很幸运 - 谢谢。只是为其他人添加一些背景信息,这只发生在我的实际设备上。 - Ian Dundas
1
尝试将 searchController.hidesNavigationBarDuringPresentation = false。 - Kevin
13个回答

70

我不确定问题的具体原因,但我通过以下方式“修复”了它:

self.searchController.hidesNavigationBarDuringPresentation = NO;
self.definesPresentationContext = NO;

我的猜测是,UISearchController 在尝试呈现为导航栏时可能会有一些奇怪的事情发生。因此,这只是一个hack,但至少不会阻止用户。搜索栏不会进行很酷的动画效果,也不会覆盖导航栏。


7
仅需要第一行代码 searchController.hidesNavigationBarDuringPresentation = false (Swift)。 - hashier
1
是的,只需要设置searchController.hidesNavigationBarDuringPresentation = false,这才是真正的解决方案。 - Kevin
不,这不是一个真正的解决方案。如果我们需要隐藏导航栏并且搜索栏被隐藏在状态栏下面怎么办? - Anees
我需要这两个。 - devjme
这应该是被接受的答案。这是唯一对我有用的东西。谢谢。 - the_critic
这仍然是我找到的唯一修复问题的答案。同意上面的评论,第一部分已经足够了。 - cscott530

66

似乎我们都遇到了同样的问题,但是它们被以不同的方式解决了。然而,没有一个建议的答案适用于我 :( 。无论如何,感谢大家抽出时间来帮助。

我找到了一个解决我的问题的方案。在故事板中使用界面构建器将(MyModalView: UITableViewController)的“扩展边缘-不透明条下方”设置为true即可。

总之:

MyModalView:UITableViewController,在故事板中使用界面构建器具有

扩展边缘: - 在顶部的下面打勾 - 在底部的下面打勾 - 在不透明条下面打勾

截图


没错。扩展边缘:在Storyboard中选中不透明栏即可解决问题。 - Cyupa
这个问题困扰了我好几个小时,非常感谢你。 - modesitt
这些复选框对应哪些属性?许多人不使用界面构建器。 - alekop

36

我发现是Storyboard中模拟的指标(顶部栏)导致了这个问题。在我的情况下,以下代码可以解决问题,但我仍然不知道为什么。

- (void)willPresentSearchController:(UISearchController *)searchController {
    // do something before the search controller is presented
    self.navigationController.navigationBar.translucent = YES;
}

-(void)willDismissSearchController:(UISearchController *)searchController
{
    self.navigationController.navigationBar.translucent = NO;
}

即使是纯代码,这种情况也会发生。我敢打赌,translucent = false 实际上是删除了视图或类似的东西,而不是禁用透明效果,因此搜索栏简单地超出了可见区域。 - jigzat
2
不要忘记将searchController的代理设置为实现这些方法的类(通常是self)。 - lbarbosa
这就是让我成功的解决方案!谢谢! - D6mi
willPresent 中使用 .default,在 willDismiss 中使用 .minimal 对我很有帮助。 - Nike Kov
解决了我们的问题 - 在我们的情况下,navigationBar 重叠了 searchBar - 在委托内部设置半透明开/关修复了该问题。 - hibento

19
我必须
self.aNavigationController?.extendedLayoutIncludesOpaqueBars = true

我在这里找到了一个类似的问题(链接),但在我的情况下,问题不是在viewDidLoad方法中出现的。 我不得不尝试不同的视图,直到它起作用。现在我可以同时拥有自定义导航栏颜色和搜索栏。


1
太棒了,Jigzat! - Naga Mallesh Maddali
这应该与@David Trang的答案一起添加。 - Augustine P A

10

感谢 @wiles duan 和 @Techprimate

在我的情况下,我通过设置以下内容来解决了这个问题:

self.definesPresentationContext = NO;

请在UISearchControllerDelegate中实现以下两个方法

- (void)willPresentSearchController:(UISearchController *)searchController {
    // do something before the search controller is presented
    self.navigationController.navigationBar.translucent = YES;
}

-(void)willDismissSearchController:(UISearchController *)searchController
{
    self.navigationController.navigationBar.translucent = NO;
}

1
我通过实现委托方法来修复我的问题。 - jaytrixz

6
在我的情况下,我通过删除 definesPresentationContext = true 来解决了这个问题。我尚未测试删除此内容是否有任何缺点!

这个修改对我来说解决了问题。 - Jeff

3
我曾遇到相同的问题,当我在 Xcode 上调试 UI 时发现 UISearchBar 视图被移动到另一个视图并且宽度被清零了。
我通过将 UISearchControllerdefinesPresentationContext 属性设置为 false,并将其设置为 true 来修复这个问题,对于包含的 UITableViewController 也是如此。
我只添加了一行代码到你的 viewDidLoad() 中。
override func viewDidLoad() {
    super.viewDidLoad()

    // Dynamically create a search controller using anonymous function
    self.resultSearchController = ({
        let controller = UISearchController(searchResultsController: nil)
        controller.searchResultsUpdater = self
        controller.dimsBackgroundDuringPresentation = false
        controller.definesPresentationContext = false    // Disable the presentation controller

        controller.searchBar.sizeToFit()
        controller.searchBar.delegate = self

        self.tableView.tableHeaderView = controller.searchBar

        return controller
    })()

    // Auto sizing row & cell height
    self.tableView.estimatedRowHeight = 130
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.definesPresentationContext = true    // This one remains the same

    // No footer for better presentation
    self.tableView.tableFooterView = UIView.init(frame: CGRectZero)
}

2

在这个应用程序的某个地方,我没有导航栏。其他SO帖子都没有帮助我,所以我通过以下方式解决了这个问题:

- (void)layoutSubviews
{
    [[[self searchController] searchBar] sizeToFit];
}

1
在Storyboard中将navigationBar永久设置为半透明可以解决我的问题。

1

它可以工作

override func viewDidLoad() {
    super.viewDidLoad()

    self.extendedLayoutIncludesOpaqueBars = !self.navigationController!.navigationBar.translucent
}

我不得不在viewDidAppear中这样做,否则它会再次出现问题。感谢@Apple。 - EralpB
这个对我也解决了问题。谢谢。 - mikengyn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接