状态栏和导航栏显示在iOS 7中的视图边界上

bee*_*con 434 ios ios7

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

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

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

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

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

我该如何解决这个问题?

更新:

我找到了解决这个特定问题的方法.将导航栏的半透明属性设置为NO:

self.navigationController.navigationBar.translucent = NO;
Run Code Online (Sandbox Code Playgroud)

这将修复视图在导航栏和状态栏下面的框架.

但是,当您希望导航栏为半透明时,我还没有找到解决此案例的方法.例如,在全屏查看照片时,我希望导航栏是半透明的,并且要在其下方构建视图.这是有效的,但当我切换显示/隐藏导航栏时,我经历了甚至更奇怪的结果.第一个子视图(UIScrollView)每次都会更改其边界.

Nan*_*dha 495

您可以通过实现edgesForExtendedLayoutiOS7 SDK中调用的新属性来实现此目的.请添加以下代码来实现此目的,

if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
        self.edgesForExtendedLayout = UIRectEdgeNone;
Run Code Online (Sandbox Code Playgroud)

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

iOS 7对您布局和自定义UI外观的方式进行了一些更改.视图控制器布局,色调颜色和字体的更改会影响应用程序中的所有UIKit对象.此外,手势识别器API的增强功能可让您对手势交互进行更精细的控制.

使用视图控制器

In iOS 7, view controllers use full-screen layout. At the same time, iOS 7 gives you more granular control over the way a view controller lays out its views. In particular, the concept of full-screen layout has been refined to let a view controller specify the layout of each edge of its view.

The wantsFullScreenLayout view controller property is deprecated in iOS 7. If you currently specify wantsFullScreenLayout = NO, the view controller may display its content at an unexpected screen location when it runs in iOS 7.

To adjust how a view controller lays out its views, UIViewController provides the following properties:

  • edgesForExtendedLayout

除了指定none和all之外,该edgesForExtendedLayout属性使用UIRectEdgetype来指定每个矩形的四个边.使用edgesForExtendedLayout指定哪些视图的边缘应该扩展,而不管杆半透明的.默认情况下,此属性的值为UIRectEdgeAll.

  • extendedLayoutIncludesOpaqueBars

如果您的设计使用不透明条形,请edgesForExtendedLayout通过将extendedLayoutIncludesOpaqueBars属性设置为NO来进行 细化.(的默认值extendedLayoutIncludesOpaqueBars是NO.)

  • automaticallyAdjustsScrollViewInsets

如果您不希望自动调整滚动视图的内容插入,请设置automaticallyAdjustsScrollViewInsets为NO.(的默认值automaticallyAdjustsScrollViewInsets是YES).

  • topLayoutGuide,bottomLayoutGuide

The topLayoutGuide and bottomLayoutGuide properties indicate the location of the top or bottom bar edges in a view controller’s view. If bars should overlap the top or bottom of a view, you can use Interface Builder to position the view relative to the bar by creating constraints to the bottom of topLayoutGuide or to the top of bottomLayoutGuide. (If no bars should overlap the view, the bottom of topLayoutGuide is the same as the top of the view and the top of bottomLayoutGuide is the same as the bottom of the view.) Both properties are lazily created when requested.

Please refer, apple doc

  • 如果我没有导航栏,这将无效.在这种情况下,我的观点延伸到状态栏后面. (19认同)
  • 是的,那就是为什么我把if选择性检查包含在if条件中,if([self respondsToSelector:@selector(edgesForExtendedLayout)]) (8认同)
  • 它有效但......不再有半透明效果......我们怎样才能保持半透明效果...... (6认同)
  • 我和@ VanDuTran有同样的问题.如果隐藏导航栏,则edgesForExtendedLayout无效. (4认同)
  • 它不会在iOS6下编译.我认为它应该写成performselector ... (2认同)
  • @Julian将您的窗口颜色设置为您的视图背景颜色,即:[self.window setBackgroundColor:[UIColor whiteColor]]; (2认同)

Mic*_*lum 110

你不必计算将所有东西都移动下来的距离,这里有一个属性的内置.在Interface Builder中,突出显示视图控制器,然后导航到属性检查器.在这里,您会看到"Extend Edges"字样旁边的一些复选框.正如您所看到的,在第一个屏幕截图中,默认选择是内容显示在顶部和底部条形下,而不是在不透明条形下,这就是为什么将条形样式设置为不半透明的原因.

正如您在第一个屏幕截图中看到的那样,导航栏下方隐藏了两个UI元素.(我在IB中启用了线框来说明这一点)这些元素,UIButton和UISegmentedControl都将其"y"原点设置为零,并且视图控制器设置为允许顶部栏下方的内容.

在此输入图像描述

第二个屏幕截图显示取消选中"Under Top Bars"复选框时会发生什么.如您所见,视图控制器视图已正确向下移动,其y原点位于导航栏下方.

在此输入图像描述

这也可以通过使用来以编程方式完成-[UIViewController edgesForExtendedLayout].这是一个指向edgeForExtendedLayout和UIRectEdge的类引用的链接

[self setEdgesForExtendedLayout:UIRectEdgeNone];
Run Code Online (Sandbox Code Playgroud)

  • 如何只在.xib中查看相同的内容? (15认同)
  • @bobics XIB问题的答案是,"你做不到." 反正不是通过IB.提交雷达并希望Apple最终解决它. (5认同)
  • 我在视图上添加了一个标签,我按照你的指示,但这不适合我 (2认同)

Stu*_*ner 33

我以编程方式创建了我的视图,最终为我工作:

- (void) viewDidLayoutSubviews {
    // only works for iOS 7+
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        CGRect viewBounds = self.view.bounds;
        CGFloat topBarOffset = self.topLayoutGuide.length;

        // snaps the view under the status bar (iOS 6 style)
        viewBounds.origin.y = topBarOffset * -1;

        // shrink the bounds of your view to compensate for the offset
        viewBounds.size.height = viewBounds.size.height + (topBarOffset * -1);
        self.view.bounds = viewBounds;
    }
}
Run Code Online (Sandbox Code Playgroud)

来源(在第39页底部的topLayoutGuide部分).


flo*_*_23 29

Swift 3/Swift 4解决方案,也适用于iOS 10+中的NIB/XIB文件:

override func viewDidLoad() {
    super.viewDidLoad()

    edgesForExtendedLayout = []
}
Run Code Online (Sandbox Code Playgroud)


Mag*_*nus 10

如果您希望视图具有半透明导航栏(这很好),您必须设置contentInset或类似.

我是这样做的:

// Check if we are running on ios7
if([[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."][0] intValue] >= 7) {
      CGRect statusBarViewRect = [[UIApplication sharedApplication] statusBarFrame];
      float heightPadding = statusBarViewRect.size.height+self.navigationController.navigationBar.frame.size.height;

      myContentView.contentInset = UIEdgeInsetsMake(heightPadding, 0.0, 0.0, 0.0);
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么你不能直接将它与7.0进行比较 (3认同)
  • 我的tabbar后面显示了我的tableView beeing的问题.这使我的表的最后一行永远不会滚动到Tabbar上方.我修复它:myTableView.contentInset = UIEdgeInsetsMake(0,0.0,TabbarHeight,0) (2认同)

Ida*_*dan 9

在您的应用程序plist文件中添加一行,将其命名为"查看基于控制器的状态栏外观"并将其设置为NO.


Raj*_*dal 9

edgesForExtendedLayout适用于iOS 7的技巧.但是,如果您在iOS 7 SDK中构建应用程序并将其部署在iOS 6中,导航栏将显示为半透明且视图位于其下方.因此,要为iOS 7和iOS 6修复它,请执行以下操作:

self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque;
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;   // iOS 7 specific
Run Code Online (Sandbox Code Playgroud)


Ris*_*kov 7

最简单的技巧是打开NIB文件并执行以下两个简单步骤:

  1. 只需切换并将其设置为您喜欢的那个:

在此输入图像描述

  1. 选择那些你想要向下移动的UIView/UIIMageView/.... 在我的情况下,只有徽标重叠,我已将delta设置为+15; (如果您在步骤1中选择了iOS 7,则为-15)

在此输入图像描述

而结果:

之前 后

  • 它有效,但这看起来像一个难以维护的解决方案.最好只修复问题而不是修补它. (6认同)

fat*_*han 5

Swift解决方案:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.edgesForExtendedLayout = UIRectEdge.None
}
Run Code Online (Sandbox Code Playgroud)

  • 现在是edgesForExtendedLayout = [] (4认同)