当UISearchBar处于激活状态时,UITableView的内容会重叠在状态栏上。

31
我有一个UITableViewController,其中包含一个UISearchBar和UISearchDisplayController。它存在于UIViewController中的Container View中,并位于UINavigationController中。我制作了这张图片来描述结构:

enter image description here

这是它真实的样子:

enter image description here

当我点击搜索栏时,我必须隐藏导航栏。通常情况下,这会自动发生,但由于我的UITableViewController位于Container View中,我必须自己处理此更改。这就是当时的效果,注意状态栏是白色的,因为导航栏是白色的,即使此时被隐藏。

enter image description here

一旦我开始输入一些搜索文本,结果会显示出来。如果我向上滚动这些结果,它们会从搜索栏下面经过,但它们会重叠在状态栏上,非常不吸引人。

enter image description here

如果没有Container View参与,那么所有内容都按预期工作,表格内容会从状态栏下方通过,但涉及到ContainerView时,表格文本和状态栏会发生碰撞。
如何让文本像平常一样在状态栏下面移动?
8个回答

37
我搜索了好几个小时,最终得出的结果是在viewDidLoad中加入以下代码: self.extendedLayoutIncludesOpaqueBars = YES; 问题解决了 :)

这真的很有帮助,尽管我的问题不同!我的问题是当搜索栏处于活动状态时,我无法控制状态栏的背景颜色。谢谢。 - Sid
1
只是给那些遇到这个问题的人。请确保在containerViewController和searchResultsViewController中添加self.extendedLayoutIncludesOpaqueBars = YES - amol-c
您还可以从Storyboard中视图控制器的属性检查器中进行此操作(检查“扩展边缘”->“在不透明栏下方”)。 - Jovan Jovanovski
definesPresentationContext = true 和 self.extendedLayoutIncludesOpaqueBars = true 的设置解决了我的问题! - SDW

5

尝试在你的TableViewControllerviewDidLoad中设置definesPresentationContext

Swift

override func viewDidLoad() {
    super.viewDidLoad()

    definesPresentationContext = true
}

Objective-C

- (void)viewDidLoad {
    [super viewDidLoad];

    self.definesPresentationContext = YES;
}

4
以下是我的经验:

操作方法:

  • 使用UISearchController(而不是单独放置的UISearchBar)
  • 如果还没有,将您的VC放在UINavigationController中。如果需要,设置导航不显示导航栏。
  • 对于UITableView,使用自动布局(而不是弹簧和支架),并将表格顶部固定到VC视图的顶部。
  • 添加此委托方法:

- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar { return UIBarPositionTopAttached; }

不要这样做:

  • 调整edgesForExtendedLayout
  • 调整extendedLayoutIncludesOpaqueBars
  • 调整表格的contentInset

3

基本上这是由于导航栏的半透明性所致,通常情况下,视图控制器会通过纠正拥有的视图或子视图的顶部插图(如果它们是(或继承自)UIScrollView)来修正重叠。你有两个选择,一个是将导航栏的半透明设置为不透明,另一个是将 edgeForExtendedLayout 设置为 none 或仅保留底部。

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
    self.navigationController.navigationBar.translucent = YES;
}

- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller {
    self.navigationController.navigationBar.translucent = NO;
}

这些建议仅适用于iOS7,如果您部署的目标版本低于此,请在设置这些属性之前进行检查。
另一种方法是读取--topLayoutGuide的长度,并在- searchDisplayControllerWillBeginSearch中尝试设置相同长度的topInsets。 这样,您应该仍然可以保持透明度。


我遇到了与OP完全相同的问题,但我没有显示NavBar。这是在一个导航控制器中,我将其作为模态弹出窗口进行转换。由于我没有显示NavBar,因此设置透明度无法解决问题。 - Peter
尝试使用edgesForExtendedLayout。 - Andrea
更有可能也是.. -setAutomaticallyAdjustScrollInsets - Andrea
不幸的是,这两个都没有帮助。我最终使用了一个导航栏。 - Peter

3

我是一名有用的助手,可以为您翻译文本。

我有UISearchBar和UISearchDisplayController。

在viewdidload中:

self.edgesForExtendedLayout = UIRectEdgeNone;
[searchDisplayController.searchBar setBackgroundImage:[self imageWithColor:ETSBaseColor] forBarPosition:0 barMetrics:UIBarMetricsDefault];

从UIColor获取图像的方法:

- (UIImage *)imageWithColor:(UIColor *)color
{
    CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

0
在我的情况下,我不想隐藏UINavigationBar,但我遇到了类似于间隙和其他副作用的问题。其中一个问题是,在UISearchDisplayController可见的情况下,在UIViewController之间切换后,缺少了UISearchBar(我使用SWRevealViewController在UIViewController之间进行切换)。这个问题只发生在iPad上。结果发现UISearchBar突然隐藏在UINavigationBar后面。现在我通过以下代码解决了所有问题,这些代码位于在UIContainerView中呈现的UITableViewController中:
- (UINavigationController *)navigationController {
    return nil;
}

这些代码行可以防止UISearchDisplayController访问和更改我的UINavigationController。我还将此方法子类化为“MyContainerTableViewController”类,并现在将此类用于所有嵌入的UITableViewController。

我仍然使用UISearchDisplayController来支持iOS 7。


0

我也遇到了同样的问题:

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller
{
    controller.searchBar.searchBarStyle = UISearchBarStyleDefault; // Used to cover UIStatusBar
}

- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
    controller.searchBar.searchBarStyle = UISearchBarStyleMinimal; // Used not to show top and bottom separator lines
}

0

以下的方法对我有效:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return (self.searchController.isActive  && section == 0) ? 22.0f : 0.0f;
}

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