导航栏出现在带有新iOS7 SDK的视图上方


113
CGRect cgRect1 = [[UIScreen mainScreen] applicationFrame];


UISearchBar  *mySearchBar = [[UISearchBar alloc] 
               initWithFrame:CGRectMake(0, 0, cgRect.size.width, 40)];

mySearchBar.autoresizingMask = 
              UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight ;


UITableView  *myTableView = [[UITableView alloc] 
     initWithFrame:CGRectMake(0, 40, cgRect.size.width, cgRect.size.height-40)];

myTableView.autoresizingMask = 
               UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;


[self.view addSubview:mySearchBar];
[self.view addSubview:myTableView];

在早期版本中,它可以正常工作。搜索栏出现在statusbar和导航栏下方。该tableview是出现在搜索栏下方

但是,当我在该菜单上运行时Xcode 5 sdk iOS 7,搜索栏不可见(我认为它位于状态栏和导航栏下方),并且导航栏也出现在表格视图上方。

可以通过iOS 7稳定的发行版进行修复吗?

还是我的编码问题?

还是应该通过添加的y (y = statubar height + nav bar height)值来处理它iOS 7

我最近下载了Xcode 5 DP来在iOS 7中测试我的应用程序。我注意到并确认的第一件事是,视图的边界并不一定总是调整为适应状态栏和导航栏的大小。

在viewDidLayoutSubviews中,我打印视图的边界:

{{0, 0}, {320, 568}}

这导致我的内容出现在导航栏和状态栏下方。

我知道我可以通过获取主屏幕的高度,减去状态栏的高度和导航栏的高度来自己计算高度,但这似乎是不必要的额外工作。

还有其他人遇到过这个问题吗?

更新:

我已经找到了针对此特定问题的解决方案。将导航栏的半透明属性设置为NO:

self.navigationController.navigationBar.translucent = NO;

这样可以防止视图被框在导航栏和状态栏的下面。

但是,当您希望导航栏为半透明时,我还没有找到针对这种情况的解决方案。例如,以全屏方式查看照片时,我希望导航栏是半透明的,并且视图应位于其下方。那行得通,但是当我切换显示/隐藏导航栏时,我什至遇到了奇怪的结果。第一个子视图(a UIScrollView)的界限y每次更改的原点。


4
Beta软件。苹果开发者论坛更为合适。另外,该问题在过渡指南中已明确提及。
苏珊(Sulthan)2013年

Answers:


188

并非完全如此。iOS 7中引入了一个新属性,使您可以像以前版本的iOS中一样调整布局行为。将这段代码放在您的视图控制器中,您应该一切顺利!导航栏占用的空间应自动考虑

 if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;

您需要在-(void)viewDidLoad方法中添加以上内容。

注意:由于API已从Beta版更改,因此您现在应该使用iOS 7和Xcode 5的最新GM版本。


在我的代码中,它说的是edgesForExtendedLayout。使用未声明的标识符UIExtendedEdgeNone。请帮忙。

6
它已更改为UIRectEdgeNone
Simon

6
这就是为什么不应在此处提出或回答这样一个问题的原因。
苏珊(Sulthan)2013年

我不知道为什么已了解,如果你想保持与iOS6的兼容性你不得不通过代码引入有条件的情况下,以检查是否控制器具有财产或不..
jerrygdm

12
仅当视图嵌入在UINavigationController中时,这才似乎有效。
pojo 2013年

37

故事板的屏幕截图

如果您在Storyboard中工作(强烈建议!),这是解决方案: 您可以在Storyboard中禁用ViewController的“扩展边缘”。您必须为每个viewController执行此操作。您可以通过单击stortyboard中的viewController图标(在视图本身下方的productOwner旁边),然后选择属性检查器(如图像所示)来禁用扩展边缘。

这还将设置对齐线,如iOS 6。

xCode 5中的另一个很棒的工具是“预览”:单击男管家按钮(辅助编辑器),然后选择“预览”。您可以在其中选择iOS 6,然后查看故事板设计在iOS 6上的外观。

太好了:D

[更新]

请注意:当应用进入iOS7的背景时,禁用“扩展边缘”可能会导致导航栏上出现黑光。发光也将在多任务视图中可见(双击主屏幕按钮)。这可以通过将导航栏视图的背景色设置为白色来解决。

[self.navigationController.view setBackgroundColor:[UIColor whiteColor]];

是的,这是从分镜脚本的角度来看的解决方案。谢谢。
jpittman 2014年

12

正如OP所说,对此有一个简单的解决方案,就是将导航栏设置为不透明。无需在代码中执行此操作,只需在根导航栏中取消选中“半透明”即可:

在此处输入图片说明


8

self.edgesForExtendedLayout=UIRectEdgeNone;

它适用于iOS 7模拟器(Xcode 5 DP5)


2
这在ios7中可以正常工作,但是如果我在ios 6和更早的版本上运行该应用程序,则视图将向上移动。任何解决方案?还需要在每个视图控制器viewdid加载方法中设置此属性吗?
loganathan 2013年

您可以随时通过以下方法检查当前的iOS版本是否为7:if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1)
Aviel Gross 2013年

2

这些答案都是有帮助的,尤其是MQoder的答案,但是对我来说,我还必须将默认的顶部栏设置为“不透明的黑色导航”。

在此处输入图片说明


1

@One Man Crew的答案是正确的,但是:

我建议使用此代码来避免在旧版本上运行该应用程序时出现错误:

 #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_6_1
     if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;
 #endif

0

self.edgesForExtendedLayout = UIRectEdgeNone;

您需要在AppDelegate#application:didFinishLaunchingWithOptions上执行此操作:

self.window.backgroundColor = [UIColor whiteColor];

否则,导航栏的背景颜色将变为灰色。因为透明的导航栏与窗口重叠。


0

如果要在用户滚动表格视图时保持透明度,则可以设置其contentInset:

CGFloat topLayoutGuide = self.topLayoutGuide.length + self.tabBarController.navigationController.navigationBar.frame.size.height;
self.tableView.contentInset = UIEdgeInsetsMake(topLayoutGuide, 0, 0, 0);

-1

一种解决方案是使用导航控制器。这样可以自动解决问题。还应使用Xcode 5而不是Xcode Preview版本,因为它们是beta版本。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.