我已经阅读了很多有关iOS7 UI过渡的文章。
我不能够得到什么这三个属性automaticallyAdjustsScrollViewInsets
,extendedLayoutIncludesOpaqueBars
,edgesForExtendedLayout
?
例如,我试图使我的视图控制器在状态栏下方启动,但我无法实现。
我已经阅读了很多有关iOS7 UI过渡的文章。
我不能够得到什么这三个属性automaticallyAdjustsScrollViewInsets
,extendedLayoutIncludesOpaqueBars
,edgesForExtendedLayout
?
例如,我试图使我的视图控制器在状态栏下方启动,但我无法实现。
Answers:
从iOS7开始,视图控制器默认使用全屏布局。同时,您可以更好地控制其布局视图的方式,并且可以通过以下属性来实现:
edgeForExtendedLayout
基本上,使用此属性可以设置可以扩展视图的哪一部分以覆盖整个屏幕。想象一下,您将a推UIViewController
入UINavigationController
。当布局该视图控制器的视图时,它将在导航栏结束的地方开始,但是此属性将设置可以扩展视图的哪一侧(顶部,左侧,底部,右侧)以填充整个屏幕。
让我们看一个例子:
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];
结果:
自动调整ScrollViewInsets
当视图为UIScrollView
或类似视图(例如)时,将使用此属性UITableView
。您希望表格从导航栏结束处开始,因为如果没有,您将看不到整个内容,但是同时您希望表格在滚动时覆盖整个屏幕。在这种情况下,设置edgesForExtendedLayout
为“无”将不起作用,因为您的表格将在滚动条结束处开始滚动并且不会在表格后面滚动。
这是此属性派上用场的地方,如果让视图控制器自动调整插图(将此属性设置为YES,也是默认值),它将在表格顶部添加插图,因此表格将在导航位置开始条结束,但滚动条将覆盖整个屏幕。
这是设置为“否”的时间:
和是(默认情况下):
在这两种情况下,表格都在导航栏后面滚动,但在第二种情况下(YES),它将从导航栏下面开始。
extendedLayoutIncludesOpaqueBars
该值只是先前值的附加值。默认情况下,此参数设置为NO。如果状态栏是不透明的,该意见将不会被扩展到包括状态栏,即使您扩展视图来覆盖它(edgesForExtendedLayout
到UIRectEdgeAll
)。
如果将值设置为YES,这将允许视图再次进入状态栏下方。
如果不清楚,请写评论,我会回答。
iOS如何知道要使用的UIScrollView?
iOS会在ViewController的视图中获取第一个子视图,该子视图位于索引0处,如果它是的子类,UIScrollView
则将说明的属性应用于它。
当然,这意味着UITableViewController
默认情况下可以工作(因为UITableView
是第一个视图)。
不确定是否使用情节提要,但如果要使用情节提要,请确保状态控制器在状态栏下方(和底部栏上方)启动:
在IB中选择视图控制器,在属性检查器中,取消选择“延伸边缘-顶部栏下方”和“延伸边缘-底部栏下方”。
我正在使用情节提要,并使用上述建议有效,但是我不确定如何实现它。下面是一个简短的示例,它通过将推荐的解决方案放入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,导致情节提要和模拟器之间存在差异
解决:应用以上代码,关闭自动调整功能。
只需记住,
automaticallyAdjustsScrollViewInsets
仅当某种滚动视图(表视图,集合视图等)是
其他建议,即使它是第一个子视图也不起作用,但是视图层次结构中还有其他滚动视图。
编辑(扩展名DIY)
如果即使您不满足这些条件,也想要类似的行为(例如,滚动视图下方有背景图像),则可以手动调整滚动视图插图。但是请不要将其设置为常数,例如44或64,甚至不要像许多SO建议的那样设置为20。您永远都不知道大小。可以有incall / gps / audio通知,导航栏不一定总是44 pts等。
我认为最好的解决方案是在didLayoutSubviews length
中使用layoutGuide:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: 0, right: 0)
scrollView.scrollIndicatorInsets = scrollView.contentInset
}
您可以以相同方式使用bottomLayoutGuide。