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);
}
}
我在 UISearchController
与 navigationItem
一起使用时遇到了类似的问题。它看起来不同,但是由完全相同的问题引起的:UISearchController
在状态栏重新出现时不更新 searchBar
框架。
但是,与其手动调整 searchBar
视图层次结构的框架,不如在 traitCollectionDidChange
或 traitCollectionDidChange
旋转期间来回切换 hidesNavigationBarDuringPresentation
来强制其更新布局。 =18=]:
所以修复看起来像这样:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if #available(iOS 11, *) {
navigationItem.hidesSearchBarWhenScrolling.toggle()
navigationItem.hidesSearchBarWhenScrolling.toggle()
}
}
这是原始问题的样子。
然后旋转得到这个:
我已经实现了 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);
}
}
我在 UISearchController
与 navigationItem
一起使用时遇到了类似的问题。它看起来不同,但是由完全相同的问题引起的:UISearchController
在状态栏重新出现时不更新 searchBar
框架。
但是,与其手动调整 searchBar
视图层次结构的框架,不如在 traitCollectionDidChange
或 traitCollectionDidChange
旋转期间来回切换 hidesNavigationBarDuringPresentation
来强制其更新布局。 =18=]:
所以修复看起来像这样:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if #available(iOS 11, *) {
navigationItem.hidesSearchBarWhenScrolling.toggle()
navigationItem.hidesSearchBarWhenScrolling.toggle()
}
}
这是原始问题的样子。
然后旋转得到这个: