UISearchBar 的范围按钮覆盖了第一行结果

Posted

技术标签:

【中文标题】UISearchBar 的范围按钮覆盖了第一行结果【英文标题】:UISearchBar's scope buttons are covering the first row of results 【发布时间】:2011-06-28 23:40:32 【问题描述】:

我是第一次使用 UISearchBar,但不能完全按照我的意愿行事。

当您激活范围按钮时,它们会覆盖表格的第一行。查看所有搜索结果的唯一方法似乎是在编辑完成后隐藏范围按钮;在我的谷歌搜索中,我看到了这个建议。

我想要 Mail 具有的功能,只要搜索框中有文本,范围按钮就会一直显示,并且您可以看到搜索结果会随着您更改活动范围按钮而发生变化。但是如果没有范围按钮覆盖表格的第一行,我想不出任何方法来实现这一点。您不能只向下滚动表格视图;搜索栏位于表格视图的标题中,因此整个内容一起滚动。

建议赞赏!

在尝试了以下 Andrew 的建议后更新。

我忘记的一件事是,在 viewDidAppear 中,我向上滚动表格视图内容,这样搜索框就离开了屏幕顶部,但可以在需要时向下滚动。这显然是我的问题的一部分。所以,在 viewDidAppear 我有

if (theSearchBar.showsScopeBar != YES) 
    [self.tableView setContentOffset:CGPointMake(0, 44) animated:YES];

在 searchBarShouldBeginEditing 中,我现在有:

[self.navigationController setNavigationBarHidden:YES];
[self.tableView setContentOffset:CGPointMake(0, -44) animated:YES];
[UIView beginAnimations:@"searchBarUp" context:nil];
[UIView setAnimationDuration:1.0f];
searchBar.frame = CGRectOffset(searchBar.frame, 0, -44);
[UIView commitAnimations];

这给出了正确的结果,但是当范围栏出现时,视图顶部和搜索栏顶部之间存在间隙,并且第一行被覆盖。然后滚动条(带有范围按钮)向上滑动到位。这显然看起来不太好。

我希望上面的代码做的是:

隐藏导航栏,这会将表格的第一行放在状态栏的正下方

向下滚动表格内容,这会将搜索栏的顶部放在状态栏的正下方

向上移动搜索栏,使搜索栏底部之间有 44 像素的间隙,由范围按钮填充

这似乎确实发生了,除了您可以看到导航栏留下的间隙,直到滚动条向上移动以满足它。你会认为这可以通过最后隐藏导航栏来解决,但是没有......当我尝试时,我最终发现表格的第一行都覆盖了 之间的导航栏大小的孔状态和搜索栏。

我觉得很奇怪的另一件事是,如果我按原样使用上面的代码 sn-p,除了在调用 setContentOffset 时使用动画:NO,我会得到不同的结果。在这种情况下,表格的第一行没有被覆盖,但搜索框位于视图顶部上方,无法向下滚动(不会留下)。只有范围按钮可见。对我来说,仅仅关闭动画就会改变结果是没有意义的。

现在,您可能认为如果所有内容都放在正确的位置,那么显示搜索结果就可以了。但不是。即使现在导航栏已经不在画面中了,但搜索栏仍然在其上方出现了很大的空隙,并且需要对表格内容和搜索栏框架进行相同的调整。

我要注意 viewWillAppear 中的代码只执行一次,因为我们从不离开视图,所以不是每次都向上重新调整表格。

我很想了解发生了什么,以及如何解决它,如果有人可以帮助阐明一些问题。

为了清楚起见再次更新 - 当我说“修复它”时,我的意思是让它看起来很好,当部件移动到位时没有明显的间隙。我什至不一定希望它动画化。滑入位置需要太长时间。但正如我上面提到的,关闭动画会使事情再次出现在错误的地方。

最后一次更新 - 我通过移除线条周围的动画块来移动搜索栏,让它看起来好多了。我猜这在动画开始之前引入了暂停。现在已经足够好了,至少目前是这样。我仍然接受安德鲁的回答,因为他把我引向了正确的方向。

【问题讨论】:

以一种非常老套的方式,删除并重新添加到表格视图的标题中,以便它知道它已被调整大小? 【参考方案1】:

在 Mail.app 的情况下,看起来他们隐藏了 UINavigationBar,如下所示:

[self.navigationController setNavigationBarHidden:YES animated:YES];

然后使用 UIView 动画,他们增加了搜索栏的大小以占用导航栏填充的空间。

伪代码:

[UIView beginAnimations:@"foo" context:NULL];
[UIView setAnimationDuration:1.0f];
CGRect newFrame = CGRectMake(0,0,self.view.frame.size.width, mySearchBar.frame.size.height);
mySearchBar.frame = newFrame;
//optionally, you could do something like this instead of setting a new frame
// mySearchBar.frame = CGRectOffset(mySearchBar.frame, 0, -44);
[UIView commitAnimations];

这都将在 UISearchBarDelegate 方法中进行

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar

那么当用户取消搜索时,

– searchBarCancelButtonClicked:

您将反转动画,并再次显示导航栏。

【讨论】:

看起来几乎正确。请注意,searchBarSearchButtonClicked 有点偏离。搜索显示控制器不会反转动画。它只会反转隐藏结果表的原因。 我们越来越近了,但它还不能正常工作。当我单击搜索框时,会发生三件事 - 导航栏消失(好),范围按钮不再覆盖表格的第一行(好),搜索框现在从视图顶部向上滚动(因此范围按钮现在位于状态栏的正下方)。而且,更奇怪的是,我无法向下滚动它 - 当你放开它时它会再次弹回,因此不再可以使用搜索栏。我尝试只隐藏导航栏,没有偏移,但这会将按钮留在顶行。很困惑! 这可以通过调整 searchBar 的 y 原点来解决。与其将其设置为 0 (看起来它上升得太高),不如尝试将其设置为 10 并看看会发生什么。或者,您可能需要将整个表格向下移动一点。所以类似于 myTable.frame = CGRectOffset(myTable.frame, 0, 10); 对不起,安德鲁,直到在上面发布了我的长时间更新后,我才看到你的评论。不过,我想我涵盖了同样的领域。我现在正在把事情放在正确的地方,但它们看起来不太好。【参考方案2】:

您使用的是 UISearchDisplayController,对吗?如果没有,你应该。它会处理你自己尝试做的很多工作,比如隐藏导航栏。

【讨论】:

其实我没有使用,因为这已经是一个表格视图——当我读到它们时, UISearchDisplayController 似乎是为了将一个临时表格视图添加到一个非表格视图控制器,显示搜索结果的目的。我还不断看到有人抱怨它们难以定制,所以我只使用了 UISearchBar。这可能是错误的选择,我显然是新手,但它现在正在工作。感谢您的回答! 它非常适合添加到现有的表格视图中。它将搜索结果表视图覆盖在您的普通表视图之上,并且您的所有表视图处理代码(UITableViewDelegate 和 UITableViewDataSource 方法)都可以用于填充它,只需少量代码更改(如果有的话)。定制并不比常规表格视图难。我很高兴你让它工作,但在未来,请考虑尝试 UISearchDisplayController...我认为从长远来看它会为你节省很多工作。 请注意,UISearchDisplayController 在 ios 8 中已被弃用。它已被 UISearchController 取代。【参考方案3】:

我也遇到了同样的问题。因为我没有使用 UISearchDisplayController(我想避免使用默认的搜索表视图)。所以我宁愿直接去搜索栏。问题是现在搜索栏嵌入在表格视图下(您可以在情节提要中检查它)。要解决此问题,您必须在 UIView 下分别嵌入表格视图和搜索栏。

【讨论】:

【参考方案4】:

这就是我所做的,我正在使用 SearchViewController:

if #available(iOS 11.0, *) 
    navigationItem.searchController = searchController
    
    else
        tableView.tableHeaderView = searchController.searchBar
    

【讨论】:

以上是关于UISearchBar 的范围按钮覆盖了第一行结果的主要内容,如果未能解决你的问题,请参考以下文章

UISearchBar 最小样式与范围按钮错误?

如何在 iOS 8 中使用 UISearchController,其中 UISearchBar 在我的导航栏中并且有范围按钮?

动态更改 UISearchBar 的键盘类型

开始编辑后关闭 UISearchBar 中的范围栏

动画 UISearchBar 框架的宽度

如何触发 UISearchBar 中的取消按钮?