我正在为 iOS 7 更新我的应用程序,并且我正在调整我的所有视图以考虑新的透明状态栏(我的应用程序仍将使用不透明的导航栏)。
在每个视图中调整状态栏相对容易,除了我在一个视图控制器中将 UISearchBar 连接到 UISearchDisplayController 时遇到的一个主要问题。
搜索栏似乎正常显示,如下图:
https://i.stack.imgur.com/GB8ye.png
问题是,一旦我开始搜索,导航栏就会消失(应该如此),但其他所有内容也会向上移动以与状态栏重叠:
https://i.stack.imgur.com/DOBsp.png
这似乎没有按预期工作,因为屏幕变暗发生在搜索栏下方 20 像素处,搜索栏应在此处结束。
iOS 7 中是否有内置解决方案?我宁愿不必在每次用户开始和结束搜索时手动调整每个视图的框架。
谢谢!
将以下行放入 viewDidLoad 为我修复它:
self.edgesForExtendedLayout = UIRectEdgeNone;
感谢 hodade 带领我走上正轨!您的解决方案有效,只是它只移动了搜索栏的框架,将我的其他子视图留在了错误的位置。我唯一改变的是移动视图中的所有子视图,并为其设置动画。
谢谢!
-(void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
[UIView animateWithDuration:0.25 animations:^{
for (UIView *subview in self.view.subviews)
subview.transform = CGAffineTransformMakeTranslation(0, statusBarFrame.size.height);
}];
}
}
-(void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
[UIView animateWithDuration:0.25 animations:^{
for (UIView *subview in self.view.subviews)
subview.transform = CGAffineTransformIdentity;
}];
}
}
你可能没有使用半透明的导航栏?如果是这样,这将解决它。
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
self.navigationController.navigationBar.translucent = YES;
}
- (void)searchDisplayControllerDidEndSearch:(UISearchDisplayController *)controller {
self.navigationController.navigationBar.translucent = NO;
}
只需将以下代码放入 -(void) ViewDidLoad。它适用于 iOS 7 及更高版本
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
更新:
if(SYSTEM_VERSION_GREATER_THAN(@"6.1")) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
我做了下面的代码来解决这个问题。
- (void) viewDidLayoutSubviews
{
if(floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
{
CGRect viewBounds = self.view.bounds;
CGFloat topBarOffset = self.topLayoutGuide.length;
viewBounds.origin.y = topBarOffset * -1;
self.view.bounds = viewBounds;
}
}
这似乎描述了我遇到的问题;希望它会帮助我以前的职位。
将已添加到 UIViewController/UITablewViewController 的 SearchDisplayController 子类化,在其实现中添加如下内容: - (void)setActive:(BOOL)visible animated:(BOOL)animated { [super setActive:visible animated:animated]; [self.searchContentsController.navigationController setNavigationBarHidden:NO动画:NO]; CGRect frame = self.searchResultsTableView.frame; frame.origin.y = CGRectGetHeight(self.searchContentsController.navigationController.navigationBar.frame); frame.size.height = CGRectGetHeight(frame) - CGRectGetMinY(frame); self.searchResultsTableView.frame = 框架;框架 = self.searchBar.frame; self.searchBar.frame = 框架; [self.searchContentsController.view insertSubview:self.searchBar aboveSubview:self.searchResultsTableView]; }
我认为也许将其添加到 viewDidLoad 会有所帮助:
if([self respondsToSelector:@selector(setEdgesForExtendedLayout:)])
{
self.edgesForExtendedLayout = UIRectEdgeNone;
}
只需添加
self.definesPresentationContext = YES;
您可以从这里了解更多信息:UISearchController and definesPresentationContext
并来自 Apple 文档:UISearchController documentation
注意:UISearchDispalyController 在 iOS7 中已弃用,在 iOS8 中使用 UISearchController 代替,上面的方法使用 UISearchController
就我而言,搜索栏下方的视图位于正确的位置,只有搜索栏与状态栏重叠。在这种情况下,这种代码的和平工作正常:
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
CGRect frame = self.searchBar.frame;
frame.origin.y += statusBarFrame.size.height;
self.searchBar.frame = frame;
}
}
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
CGRect frame = self.searchBar.frame;
frame.origin.y -= statusBarFrame.size.height;
self.searchBar.frame = frame;
}
}
希望对其他人有用
-(void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
CGRect frame = controller.searchBar.frame;
frame.origin.y += statusBarFrame.size.height;
controller.searchBar.frame = frame;
}
}
-(void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
CGRect frame = controller.searchBar.frame;
frame.origin.y -= statusBarFrame.size.height;
controller.searchBar.frame = frame;
}
}
仅当您的导航栏未隐藏时,上述答案才有效。如果您隐藏了导航栏,请尝试以下操作:
-(void)viewDidAppear:(BOOL)animated{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
[self.tableView setFrame:CGRectMake(self.tableView.frame.origin.x, self.tableView.frame.origin.y+statusBarFrame.size.height, self.tableView.frame.size.width, self.tableView.frame.size.height)];
}
}
基于这篇文章:UISearchBar overlaps status bar in iOS
将已添加到 UIViewController/UITablewViewController
的 SearchDisplayController
子类化并将其添加到其实现中 -
- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
if(self.active == visible) return;
[self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
[super setActive:visible animated:animated];
[self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
if (visible) {
[self.searchBar becomeFirstResponder];
} else {
[self.searchBar resignFirstResponder];
}
}
self.edgesForExtendedLayout = UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight;
可能是一个更好、更通用的解决方案。 (这将保留其他边缘的扩展布局,这对于屏幕底部模糊的工具栏之类的东西很重要。)if ([self respondsToSelector:@selector(edgesForExtendedLayout)]){self.edgesForExtendedLayout = UIRectEdgeNone;}