在导航控制器中默认隐藏 UITableView 搜索栏

Posted

技术标签:

【中文标题】在导航控制器中默认隐藏 UITableView 搜索栏【英文标题】:Hide UITableView search bar by default when in a navigation controller 【发布时间】:2010-11-25 01:07:54 【问题描述】:

我已经阅读了多篇关于此的帖子,但它对我来说无法正常工作。我正在使用最新的 4.2 SDK。

我的代码是

self.tableView.contentOffset = CGPointMake(0.0, 44.0);

这部分有效,它将搜索栏向上移动了一点,但并没有完全隐藏。我已经尝试将值 44 增加到更大的值,这对以往没有任何影响!我在表的视图控制器的 viewDidLoad 方法中调用此代码。有人有什么想法吗?

【问题讨论】:

您能解释一下您是如何布置表格视图的吗? 我会查看wantsFullScreenLayout。如果您在底部有一个栏将覆盖表格的一部分,您可以添加一个 44px 高的页脚视图(快速简单),或者您可以将表格视图放入父视图(更多的工作但更清洁)。 【参考方案1】:

另一种方法应该是...在 viewDidLoad 调用中:

self.tableView.contentInset = UIEdgeInsetsMake(-self.searchDisplayController.searchBar.frame.size.height, 0, 0, 0);

并实现endDragging委托方法:

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
    CGPoint offset = self.tableView.contentOffset;

    CGFloat barHeight = self.searchDisplayController.searchBar.frame.size.height;
    if (offset.y <= barHeight/2.0f) 
        self.tableView.contentInset = UIEdgeInsetsZero;
     else 
        self.tableView.contentInset = UIEdgeInsetsMake(-barHeight, 0, 0, 0);
    

    self.tableView.contentOffset = offset;

设置内容是为了去除一些“闪烁”

如果您希望搜索栏位于顶部,请以这种方式实现 didScroll:

-(void)scrollViewDidScroll:(UIScrollView *)scrollView
     CGRect sbFrame = self.searchDisplayController.searchBar.frame;
     sbFrame.origin.y = self.tableView.contentOffset.y;
     if (sbFrame.origin.y > 0) 
         sbFrame.origin.y = 0;
     
     self.searchDisplayController.searchBar.frame = sbFrame;

我希望这会有所帮助(我花了几天时间才弄清楚:))

干杯!

更新:

正如@carbonr 所说,你应该在 viewDidLoad 中添加这一行,因为 ios7+

self.edgesForExtendedLayout = UIRectEdgeNone;

【讨论】:

谢谢!这正是我缺少的“设置内容偏移以消除闪烁”部分。 @GrizzlyNetch 非常感谢!!!!很棒的解决方案,我已经挣扎了很长时间。这个解决方案的另一个作用是,当用户点击 iPhone 的顶部(应用程序之外)时,表格视图会滚动到顶部但隐藏滚动条,除非他在那之后将其拉下。 @GrizzlyNetch 我有一个疑问,在 scrollViewDidEndDragging 实现中,我们需要检查正在滚动的表格视图是 self.searchDisplayController.searchResultsTableView 还是 self.tableView。 @user1046037 优化的好点,但我认为它也会以这种方式工作。但可以肯定的是,最好检查一下哪个表被拖动了。 代码在 iOS 7 上会出现异常行为,要解决这个问题,您需要将其添加到您的 viewDidLoad。这是一个新的 API self.edgesForExtendedLayout = UIRectEdgeNone;【参考方案2】:
self.tableView.contentOffset = CGPointMake(0.0, 44.0);

上面的代码确实有效,但它需要在 UITableView 完成创建所有单元格后运行。我想那是另一个问题。

【讨论】:

您是如何确保 tableview 已完成创建所有单元格的?你能给我一些线索吗?谢谢!【参考方案3】:

您可以在viewDidLoad 中设置表格视图的初始边界,因此搜索栏在开头显示为隐藏。

您必须创建searchBar 属性,然后使用以下代码:

- (void)viewDidLoad

    //...
    CGRect bounds = self.tableView.bounds;
    bounds.origin.y = self.tableView.bounds.origin.y + searchBar.bounds.size.height;
    self.tableView.bounds = bounds;
    //...

【讨论】:

【参考方案4】:

对于仍在寻找更新解决方案的其他人,您可以通过 here 查看我的回答。

基本上你需要在第一次调用viewDidLayoutSubviews 时更新contentOffset

【讨论】:

【参考方案5】:

我也有和你一样的问题。以下代码解决了我的问题。请在 viewDidLoad() 中添加代码:

self.edgesForExtendedLayout = UIRectEdgeNone;

N:B:我在项目中使用了 autoLayout。

【讨论】:

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

UITableView 和分段控制器在 IOS 11 导航栏下移动

防止 UISearchController 在 IOS8 中隐藏视图导航栏

UITableView 部分索引在 iOS 7 中定位错误的单元格,顶行隐藏在导航栏下

使用 self.navigationController.hidesBarsOnSwipe = true 隐藏导航栏,将其永久隐藏

如何在 Mac Catalyst 应用程序中禁用默认键盘导航?

如何在我的自定义导航控制器中隐藏标签栏?