253

我已经阅读了很多关于 iOS7 UI 转换的内容。

我无法获得这三个属性automaticallyAdjustsScrollViewInsets,,??extendedLayoutIncludesOpaqueBarsedgesForExtendedLayout

例如,我试图让我的视图控制器在状态栏下方开始,但我无法实现它。

4

5 回答 5

635

从 iOS7 开始,视图控制器默认使用全屏布局。同时,您可以更好地控制视图的布局方式,这可以通过以下属性完成:

edgeForExtendedLayout

基本上,使用此属性,您可以设置视图的哪些边可以扩展以覆盖整个屏幕。想象一下,您将 a 推UIViewController入 aUINavigationController中。当该视图控制器的视图布局时,它将从导航栏结束的位置开始,但此属性将设置视图的哪些边(上、左、下、右)可以扩展以填满整个屏幕。

让我们看一个例子:

UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];

此处您没有设置 的值edgesForExtendedLayout,因此采用默认值 ( UIRectEdgeAll),因此视图扩展其布局以填充整个屏幕。

这是结果:

扩展布局没有边缘,视图填满整个屏幕

如您所见,红色背景延伸到导航栏和状态栏的后面。

现在,您要将该值设置为UIRectEdgeNone,因此您要告诉视图控制器不要扩展视图以覆盖屏幕:

UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
viewController.edgesForExtendedLayout = UIRectEdgeNone;
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];

结果:

设置了edgesForExtendedLayout,视图就在导航下方


自动调整ScrollViewInsets

当您的视图是 aUIScrollView或类似视图时使用此属性,例如 a UITableView。您希望表格从导航栏结束的位置开始,因为如果没有,您将看不到全部内容,但同时您希望表格在滚动时覆盖整个屏幕。在这种情况下,设置edgesForExtendedLayout为 None 将不起作用,因为您的表格将开始滚动到导航栏结束的位置,并且不会移到它后面。

这里是这个属性派上用场的地方,如果你让视图控制器自动调整 insets(将此属性设置为 YES,也是默认值)它会将 insets 添加到表格的顶部,因此表格将从导航的位置开始栏结束,但滚动将覆盖整个屏幕。

这是设置为 NO 的时间:

表格将在整个屏幕上滚动,但开始部分覆盖

是的(默认情况下):

表格在整个屏幕上滚动,并在导航下方开始

在这两种情况下,表格都在导航栏后面滚动,但在第二种情况下(是),它将从导航栏下方开始。


extendedLayoutIncludesOpaqueBars

此值只是对先前值的补充。默认情况下,此参数设置为 NO。如果状态栏是不透明的,则视图不会扩展到包括状态栏,即使您扩展视图以覆盖它(edgesForExtendedLayoutUIRectEdgeAll)。

如果将值设置为 YES,这将允许视图再次进入状态栏下方。

如果有不清楚的地方,请写评论,我会回答。

iOS 如何知道要使用什么 UIScrollView?

iOS 抓取 ViewController 视图中的第一个子视图,即索引 0 处的子视图,如果它是其子类,UIScrollView则将解释的属性应用于它。

当然,这意味着UITableViewController默认情况下有效(因为这UITableView是第一个视图)。

于 2013-10-25T08:40:10.317 回答
15

不确定您是否使用情节提要,但如果是,请让您的视图控制器从状态栏下方(以及底部栏上方)开始:

在 IB 中选择视图控制器,在属性检查器中,取消选择“Extend Edges - Under Top Bars”和“Extend Edges - Under Bottom Bars”。

于 2013-09-20T16:02:19.933 回答
11

我正在使用情节提要并使用上述建议有效,但是我不确定如何实现它。下面是一个简短的示例,它通过将推荐的解决方案放入 ViewController 中来快速解决问题。

import Foundation
import UIKit

// This ViewController is connected to a view on a storyboard that 
// has a scrolling sub view.
class TheViewController: UIViewController {

  // Prepares the view prior to loading.  Putting it in viewDidAppear didn't work.
  override func viewWillAppear(animated: Bool) {

    // this method is an extension of the UIViewController 
    // so using self works as you might expect.
    self.automaticallyAdjustsScrollViewInsets = false

    // Default is "true" so this sets it to false tells it to use 
    // the storyboard as you have it placed
    // and not how it thinks it should place it.
  }

}

我的问题:默认情况下,自动调整设置为 true,导致情节提要设计和模拟器之间存在差异 自动调整默认设置为 true,导致故事板设计和模拟器之间存在差异

已解决:应用上述代码,关闭自动调整。 应用上述代码,关闭自动调整。

于 2014-11-18T16:30:47.320 回答
5

我通过添加这一行解决了这个问题,但我的问题与 a 相关UIView,而不是UIScrollView

self.navigationController.navigationBar.translucent = NO;
于 2015-08-27T21:35:17.880 回答
2

请记住,该 automaticallyAdjustsScrollViewInsets 属性仅在某种滚动视图(表格视图、集合视图......)是

  • VC的观点,或者
  • 此视图的第一个子视图

其他人建议,即使它是第一个子视图,它也不起作用,但视图层次结构中还有其他滚动视图。

编辑(扩展DIY)

如果即使您无法满足这些条件(例如,您在滚动视图下方有背景图像)也想要类似的行为,您可以手动调整滚动视图插图。但请不要像许多人建议的那样将其设置为 44 或 64 甚至 20 之类的常量。你永远无法知道大小。可以有 incall/gps/audio 通知,导航栏不必总是 44 点等。

我认为最好的解决方案是length在 didLayoutSubviews 中使用 layoutGuide:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    scrollView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: 0, right: 0)
    scrollView.scrollIndicatorInsets = scrollView.contentInset
}

您可以以相同的方式使用 bottomLayoutGuide。

于 2017-04-27T22:50:38.573 回答