UISearchController 不在旋转时重新显示导航栏

UISearchController Not Redisplaying Navigation Bar on Rotate

我已经实现了 UISearchController,它运行良好,除了...

当我单击“搜索栏”时,导航栏会按预期消失。当我将 phone 旋转到横向视图时,我得到了这个有意义的视图。

但是,当我将 phone 旋转回纵向视图(在搜索类型区域中仍处于选中状态)时,我得到以下视图。

您可以看到导航栏再也没有出现过。我觉得我正在实施一个基本的搜索控制器。 可能是什么原因造成的?

self.venueSearchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.venueSearchController.searchResultsUpdater = self;
self.venueSearchController.searchBar.delegate = self;
self.venueSearchController.dimsBackgroundDuringPresentation = NO;
self.venueSearchController.hidesNavigationBarDuringPresentation = YES;
self.venueSearchController.searchBar.frame = CGRectMake(self.venueSearchController.searchBar.frame.origin.x, self.venueSearchController.searchBar.frame.origin.y, self.venueSearchController.searchBar.frame.size.width, 44.0);

self.definesPresentationContext = YES;

self.navigationController.navigationBar.translucent = YES;
self.venueSearchController.searchBar.translucent = YES;

self.tableView.tableHeaderView = self.venueSearchController.searchBar;

我认为这可能是 UITableViewController 布局处理导航栏的方式的问题,而不是在您向后旋转的情况下出现时没有导航栏。

我认为您可以通过将 UITableViewController 替换为将 UITableView 放入其中的 UIViewController 来解决此问题。然后将 table 视图的顶部约束设置为顶部布局指南。将边约束设置为 0 的左、右、下。

这应该确保 table 始终保持在状态栏下方,并且在导航栏移动和返回时仍会正确移动。

查看此讨论:iOS 7: UITableView shows under status bar

我通过在设置中关闭 "Hide status bar" 暂时 "fixed" 这个。

您可能需要在视图控制器中实现 UIBarPositioningDelegate

self.venueSearchController.searchBar.delegate = self;

searchBar 正在寻找来自它的委托的响应。

@protocol UISearchBarDelegate <UIBarPositioningDelegate> 

将以下内容添加到您的 self(我假设它是 ViewController)

#pragma mark - <UIBarPositioningDelegate>

// Make sure NavigationBar is properly top-aligned to Status bar
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
    if (bar == self.venueSearchController.searchBar) {
        return UIBarPositionTopAttached;
    }
    else { // Handle other cases
        return UIBarPositionAny;
    }
}

当状态栏重新出现时,UISearchController 似乎忘记重置 searchBar 的框架。我认为这可能是 UISearchController 中的错误; radar 中似乎列出了一些。似乎 searchBar 的超级视图(在 UISearchController 内部)以错误的高度结束。这很令人烦恼,因为解决方案因此涉及进入 searchController 的视图层次结构,Apple 可以更改它......您可能想要添加 iOS 版本的检查,以便它仅针对指定版本运行。

如果您将下面的代码添加到您的视图控制器中,它将在特征集合更改时被调用。它会检查 a) 搜索控制器处于活动状态,b) statusBar 未隐藏,c) searchBar origin-y 为 0,如果是这样,它会增加 superview 的高度 statusBar 的高度,移动搜索栏向下。

override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
    let app = UIApplication.sharedApplication()
    if searchController!.active && !app.statusBarHidden && searchController?.searchBar.frame.origin.y == 0 {
        if let container = self.searchController?.searchBar.superview {
            container.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y, container.frame.size.width, container.frame.size.height + app.statusBarFrame.height)
        }
    }
}

Objective C

- (void) traitCollectionDidChange: (UITraitCollection *) previousTraitCollection {

    [super traitCollectionDidChange: previousTraitCollection];

    if(self.venueSearchController.active && ![UIApplication sharedApplication].statusBarHidden && self.venueSearchController.searchBar.frame.origin.y == 0)
    {
        UIView *container = self.venueSearchController.searchBar.superview;

        container.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y, container.frame.size.width, container.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height);
    }
}

我在 UISearchControllernavigationItem 一起使用时遇到了类似的问题。它看起来不同,但是由完全相同的问题引起的:UISearchController 在状态栏重新出现时不更新 searchBar 框架。

但是,与其手动调整 searchBar 视图层次结构的框架,不如在 traitCollectionDidChangetraitCollectionDidChange 旋转期间来回切换 hidesNavigationBarDuringPresentation 来强制其更新布局。 =18=]:

所以修复看起来像这样:

 override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    if #available(iOS 11, *) {
        navigationItem.hidesSearchBarWhenScrolling.toggle()
        navigationItem.hidesSearchBarWhenScrolling.toggle()
    }
}

这是原始问题的样子。

然后旋转得到这个: