UISearchController 在 table header 视图中呈现的 UISearchBar 在活动时动画效果太远

UISearchBar presented by UISearchController in table header view animates too far when active

我正在使用 UISearchController 在 tableview 的 header 视图中显示搜索栏:

...
self.searchController.hidesNavigationBarDuringPresentation = NO;            
self.presentingTVC.tableView.tableHeaderView = self.searchController.searchBar;
[self.searchController.searchBar sizeToFit];
self.presentingTVC.tableView.tableHeaderView = self.searchController.searchBar;

(需要将 tableHeaderView 属性 设置两次,否则 header 视图会与第一行重叠,c.f。a couple of answers on S.O.

这是它的外观,在不活动时就位:

搜索栏在激活时应该保持在原位 - 我不希望它向上移动以隐藏导航栏。但它意外地向下动画,在它和导航栏之间留下一个空白 space:

这是一个 video of weird search bar animation

如果我只是使用与 UISearchController 分开的搜索栏,它在激活时不会显示相同的行为。

在我的呈现视图控制器中,我有 self.definesPresentationContext = YES;self.navigationController.navigationBar.translucent = YES;,并且在 IB 中 none 的 "extend edges" 框是活动的(所有似乎都是可能的事情这可能会导致搜索演示失败,无法阅读)。

有谁知道如何阻止搜索栏向下动画?

找到了!这似乎是 viewDidLoad 中的进攻路线vc:

self.edgesForExtendedLayout = UIRectEdgeNone;

删除了它,搜索栏如预期的那样保留在原位。

好的,所以我终于找到了适合自己的解决方案。尽管我们的代码/情节提要中很可能还有其他东西(这就是为什么这是一个很难回答的问题),但在大多数情况下,我遵循了 Apple 关于 UISearchController 的教程:(https://developer.apple.com/library/ios/samplecode/TableSearch_UISearchController/Introduction/Intro.html)

几乎我的所有代码都与他们的完全相同,但我无法让搜索栏在点击其中时不跳转。所以我所做的是在我的故事板中检查 "under opaque bars" 原始 table 视图和搜索结果 table 视图。这让搜索栏停止跳跃。

但还有最后一个问题,即结果 table 视图的第一行被搜索栏隐藏了。为了解决这个问题,我将 self.tableView.contentInset = UIEdgeInsetsMake(kHeightOfTableViewCells, 0, 0, 0); 添加到结果 table 视图的 viewDidLoad 方法中。瞧!

我能够通过从 ViewController 中删除以下行来防止 UISearchBar 向下移动: self.definesPresentationContext = YES;

轮到我了。我按照WWDC示例代码也遇到了这个问题

我注意到,如果我没有设置 searchBar 的 scopeButtonTitles 属性,则 searchBar 将不可见。经过仔细检查,它只有一个 CGRectZero 框架。这意味着设置 scopeButtonTitles 会在幕后设置框架。因此,如果不想显示任何 scopeButtonTitles,但又不想将 UISearchBar 硬编码到特定高度,请将 scopeButtonTitles 设置为空数组。

self.searchController = UISearchController(searchResultsController: nil)
self.searchController.searchResultsUpdater = self
self.searchController.searchBar.scopeButtonTitles = []
self.tableView.tableHeaderView = self.searchController.searchBar

将 scopeButtonTitles 设置为 1 个字符串的数组将不会显示范围按钮标题,但仍然有处理视图的逻辑,基本上搞砸了布局。

对 Apple 质量检查团队的支持(适用于 iOS 8)

我最近才 运行 这个问题,none 的解决方案对我有用。可能是因为我的 UI 更复杂(我的 table 带有搜索支持的视图包含在 UiNavigationController 内的 UITabController 中)无论如何,上述工作人员的 none。 我可以通过在以下位置找到的这段非常简洁的代码来简单地解决我的问题:

- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
    if (bar == searchController.searchBar) {
        return UIBarPositionTopAttached;
    }
    else { // Handle other cases
        return UIBarPositionAny;
    }
}

还有一件事要补充: 将我所有控制器的层次结构设置为在不透明栏和顶部栏下扩展后,我的搜索栏开始隐藏在导航栏下并且本来会出现就在旋转可能发生之后。这对我来说是一个提示,有一些布局错误和一些关于我的布局的信息是不正确的。这个委托方法帮助我的控制器了解游牧搜索栏的情况!

在我的例子中,将导航栏设置为 self.navigationController.navigationBar.translucent = NO; 解决了这个问题。似乎搜索栏展示层在布局搜索栏时没有考虑到导航栏的半透明。

我意识到这不是一个完美的解决方案,因为导航栏的半透明可能会影响其他地方的布局,但它至少解决了可能存在非半透明导航栏的问题。

老问题,但我可以通过设置

来解决这个问题

self.extendedLayoutIncludesOpaqueBars = YES;

在我的视图控制器上。我认为问题是由于导航栏不透明,但在搜索控制器上将 hidesNavigationBarDuringPresentation 设置为 NO,导致搜索栏在聚焦时定位不正确。

definesPresentationContext = true

override func viewDidLoad() {
        super.viewDidLoad()

        searchController = UISearchController(searchResultsController: nil)
        searchController.searchResultsUpdater = self
        searchController.hidesNavigationBarDuringPresentation = false

        searchController.dimsBackgroundDuringPresentation = true
        searchController.searchBar.searchBarStyle = UISearchBarStyle.Prominent
        self.tableView.tableHeaderView = searchController.searchBar

        definesPresentationContext = true

我猜你设置了 UISearchBar frame.original.y = 64

有代码

if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {
    [self setEdgesForExtendedLayout:UIRectEdgeNone];
}

searchBar.frame = CGRectMake(0, 0, 376, 44);

洗可以帮到你

正如第一个 post 中提到的,每个人都需要不同的解决方案。所以这是我的。我必须结合此页面上提到的两件事,即:

Swift 2:

    navigationController?.navigationBar.translucent = true

    edgesForExtendedLayout = .None

取消选中 调整滚动视图插入

检查顶栏

已解决我的问题

它非常简单,只需添加 搜索栏中 table 视图的 header 视图的 clipsToBounds = true。

countryTableView.tableHeaderView?.clipsToBounds = true

如果您使用 UINavigationControllerTabBar,您 不能 使用:

self.extendedLayoutIncludesOpaqueBars = true

您将需要此解决方案:

for iOS 11 & swift 4、在viewController下面设置一行解决了我的问题(搜索框向下跳转):

self.edgesForExtendedLayout = .bottom

我的是主控制器 .xib 文件中元素的顺序。

这有效。

这没有用。