带有 UISearchController 的 UITableView 在进入结果视图并返回时进入导航栏

Posted

技术标签:

【中文标题】带有 UISearchController 的 UITableView 在进入结果视图并返回时进入导航栏【英文标题】:UITableView with UISearchController go under navbar when enter in a result view and come back 【发布时间】:2015-10-08 09:15:32 【问题描述】:

我在UINavigationBar 中有一个UITableView 和一个UISearchController 搜索栏,一切正常,但是当我推送UISearchController 的搜索结果的结果时,我回来UITableView 在下面NavBar,这就是我初始化UISearchController的方式:

        self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
        self.searchController.delegate = self;
        self.searchController.searchResultsUpdater = self;

        self.searchController.searchBar.delegate = self;
        self.searchController.dimsBackgroundDuringPresentation = NO;
        self.searchController.hidesNavigationBarDuringPresentation = NO;
        self.searchController.searchBar.placeholder = NSLocalizedString(@"Local Search", @"");
        self.searchController.searchBar.frame = CGRectMake(0, -5, [UIScreen mainScreen].bounds.size.width, 44);


        ctrl = [[UIView alloc] initWithFrame:CGRectMake(0, 0,[UIScreen mainScreen].bounds.size.width, 44)];
        ctrl.backgroundColor = [UIColor clearColor];
        ctrl.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        [ctrl addSubview:self.searchController.searchBar];
        self.navigationItem.titleView = ctrl;
        self.definesPresentationContext = YES;

搜索栏完美地显示在UINavigationBar 中,然后当我搜索某些内容并推送一个结果的视图控制器时,如下所示:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
    DetailListController *detailList = [[DetailListController alloc] init];
    [self.navigationController pushViewController:detailList animated:YES];

当我回到UITableView 这样做时:

[self.navigationController popViewControllerAnimated:YES];

UITableViewUINavigationBar 下,我该如何解决这个问题?

谢谢

【问题讨论】:

【参考方案1】:

我遇到了完全相同的问题,在显示搜索控制器的视图控制器中将 extendedLayoutIncludesOpaqueBars 设置为 YES/true,似乎可以解决它。

self.extendedLayoutIncludesOpaqueBars = YES

请注意:设置此属性会更改滚动视图的垂直内容偏移值。

【讨论】:

【参考方案2】:

这是 UIKit 中一个非常令人沮丧的错误。似乎正在发生的是呈现视图控制器的顶部布局指南被重置为 0,这意味着它现在位于导航栏下方。布局指南是只读属性,因此您无法通过直接编辑来修复它。但是,我确实想出了一个技巧来让它重置为正确的值。将此添加到您的UISearchControllerDelegate

- (void)didDismissSearchController:(UISearchController *)searchController

    UINavigationController *nav = self.navController; // you muse save this earlier

    // force to layout guide to reset by pushing a dummy controller and popping it right back
    [nav pushViewController:[UIViewController new] animated:NO];
    [nav popViewControllerAnimated:NO];

【讨论】:

有人为此打开了雷达吗? 谢谢,没有其他方法可以强制布局指南以编程方式重置吗?【参考方案3】:

我多年来一直使用UISearchController,但今天是我第一次遇到这个问题 我以前设置edgesForExtendedLayout = []extendedLayoutIncludesOpaqueBars = true 一切都很好

但今天不是,我需要将其反转为edgesForExtendedLayout = .all 它可能对你也有用!

【讨论】:

【参考方案4】:

今天遇到了这个问题,通过引用结果视图控制器的safeAreaLayoutGuide解决了

刷新结果表的内容后,您可以调用此方法:

// NOTE: this method is used to fix a known UIKit bug where search results that do not have a content
    // size that fills the view will be placed underneath the navigation bar when displayed. this hack
    // fixes this issue by resetting the contentInset based on the content size.
    private func adjustContentInsetForContentSize() 
        if collectionView.contentSize.height > view.frame.height 
            collectionView.contentInset = UIEdgeInsets.zero
         else 
            collectionView.contentInset = UIEdgeInsets(top: view.safeAreaLayoutGuide.layoutFrame.origin.y, left: 0, bottom: 0, right: 0)
        
    

本质上,问题是由于结果视图的 contentSize 高度小于视图的可视区域。结果呈现在 contentSize.height > view.frame.height 时找到,因此此 hack 将强制内容插入正确遵守安全区域布局指南。

【讨论】:

以上是关于带有 UISearchController 的 UITableView 在进入结果视图并返回时进入导航栏的主要内容,如果未能解决你的问题,请参考以下文章

带有 UISearchController 的 resultController 中的空白结果

UISearchController 位置错误,因为带有 tableview 插图

带有大标题的 UISearchController,UI 在关闭时行为不端

带有 UISearchController 的 UITableView 在进入结果视图并返回时进入导航栏

使用另一个视图控制器(带有表格视图)来显示 UISearchController 的结果

带有大标题的 UISearchController 在选项卡栏中崩溃,“只有一个带有顶部边界的调色板可以在过渡之外处于活动状态”