如何在iOS 7中防止UINavigationBar覆盖视图顶部?

100

更新到Xcode 5后,我应用程序中所有视图中的导航栏都向下移动了。以下是一些截图,第一张显示了下拉视图中的所有内容,第二张显示了所有未变动的内容。搜索栏应从导航栏开始。

All Content All Content on Idle

有人知道我怎么能解决这个问题吗?

编辑:我之前尝试过这个建议:

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

但它会产生非常奇怪的结果。

尝试解决方案

这可能是因为我在这个视图控制器下有一个“滑动菜单”,由于导航栏的透明度而出现。


这里有另一种解决此问题的方法。https://dev59.com/qq3la4cB1Zd3GeqPHRzE#51491645 - Afonso
10个回答

238

将导航栏的半透明属性设置为 NO:

self.navigationController.navigationBar.translucent = NO;

这将修复视图在导航栏和状态栏下被框架的问题。

如果您需要显示和隐藏导航栏,请使用

 if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific

在你的viewDidLoad方法中。


1
我已将此放置在viewDidLoad中,但它没有产生任何变化。 - Sam D20
13
在viewDidLayoutSubviews函数中实现。 - Hindu
1
将此代码附加到viewDidLayoutSubviews函数中即可解决问题。感谢各位的帮助! - Sam D20
@kokx 我已经按照你说的实现了,但我仍然遇到同样的问题。 - Vaibhav Gautam
1
self.edgesForExtendedLayout = UIRectEdgeNone; 帮助了我。 - luky
显示剩余5条评论

34

iOS 7 中,默认情况下所有控制器的透明属性为YES,因此您需要将透明属性设置为NO以解决此问题。

在 iOS 7 中,默认情况下所有控制器都是半透明的。如果您不希望视图透过控制器而模糊显示,则需要将控制器的“translucent”属性设置为NO。

self.navController.navigationBar.translucent = NO;

2
没有“navController”属性。请使用以下代码:self.navigationController.navigationBar.translucent = NO; - Gene Z. Ragan
我在应用程序委托中创建了一个导航栏控制器对象,并将其命名为navController。 - Sumit Mundra

21

您可以在此屏幕的视图控制器属性检查器中禁用“扩展边缘”(如下图所示):

输入图像说明


12

这也适用于iOS 8.1上的Swift。

navigationController?.navigationBar.translucent = false

8

如果您想保持导航栏的半透明效果,在您的viewDidLoad或者viewWillAppear方法最后加入以下代码:

[self.view sendSubviewToBack:self.tableView]

如果你的scrollView子类(如UITableView、UICollectionView等)在当前视图的subviews中的index为0,它将自动根据navigationBar调整插入物。而且这不会影响iOS7之前的版本中的UI。
编辑 如果你以编程方式初始化UITableView,则最好使用此代码将其添加到视图中:[self.view insertSubview:self.tableView atIndex:0];

这应该是正确的答案。如果您正在以编程方式添加子视图,则可以使用[self.view insertSubview:self.tableView atIndex:0];而不是在添加后将其发送到后面。 - smitt04
正确。但是如果我们不知道他是如何启动控制器的(通过编程方式、接口生成器),我们不能假设这是最佳解决方案。虽然我已经编辑了我的答案。 - jbouaziz
这个是有效的,但看起来像一个hack。官方文档中有关于这个的任何说明吗? - John Tracid

4

Swift 4:

在viewDidLoad方法中设置以下代码:

self.navigationController?.navigationBar.isTranslucent = false

3
您可以将此方法添加到您的视图控制器中,如此链接所示:
-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    self.searchBar.frame = 
    CGRectMake(0, self.topOfViewOffset, self.searchBar.frame.size.width, self.searchBar.frame.size.height);
}

2
另一种方法是在您的视图控制器上设置 self.automaticallyAdjustsScrollViewInsets = YES;。 这是默认启用的。但是在您的情况下:
我发现您正在使用 EGORefreshHeaderView。它会与 UITableView 的 contentInset 一起运行。因此,当您释放它时,标题将重置顶部插入而不是恢复先前的值。

-1
如果你想完全控制视图并避免iOS的错误调整,可以子类化UITableView并在-(void)willMoveToWindow:(UIWindow *)newWindow方法中调整insets(包括滚动和指示器)。对我来说很有效。

-4
另一个选项是在源代码模式下打开您的 Info.plist 文件并输入以下信息:
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>UIStatusBarHidden</key>
<true/>

希望这能有所帮助。

1
我认为这不会对视图产生任何影响。 - Enrico Susatyo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接