我一直在阅读有关iOS7 UI过渡的很多内容。
我无法获得这三个属性automaticallyAdjustsScrollViewInsets
,extendedLayoutIncludesOpaqueBars
,edgesForExtendedLayout
??
例如,我试图让我的视图控制器从状态栏下面开始,但我无法实现它。
答案 0 :(得分:600)
从iOS7开始,视图控制器默认使用全屏布局。与此同时,您可以更好地控制它的视图布局,并使用这些属性完成:
<强> edgesForExtendedLayout 强>
基本上,通过此属性,您可以设置视图的哪些边可以扩展以覆盖整个屏幕。想象一下,您将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];
结果:
<强> automaticallyAdjustsScrollViewInsets 强>
当您的视图为UIScrollView
或类似视图时,会使用此属性,例如UITableView
。您希望您的表从导航栏结束的位置开始,因为如果没有,您将看不到整个内容,但同时您希望您的表在滚动时覆盖整个屏幕。在这种情况下,将edgesForExtendedLayout
设置为无效将不起作用,因为您的表将开始滚动导航栏结束的位置,并且它不会落后于它。
这里是这个属性派上用场的地方,如果让视图控制器自动调整insets(将此属性设置为YES,也是默认值),它会将insets添加到表的顶部,这样表就会启动导航栏结束的位置,但滚动将覆盖整个屏幕。
这是设置为NO时的时间:
和(默认情况下):
在这两种情况下,表格都会在导航栏后面滚动,但在第二种情况下(是),它会从导航栏下方开始。
<强> extendedLayoutIncludesOpaqueBars 强>
这个值只是对以前的值的补充。默认情况下,此参数设置为NO。如果状态栏不透明,则视图不会扩展为包含状态栏,即使您将视图扩展为覆盖它(edgesForExtendedLayout
到UIRectEdgeAll
)。
如果您将值设置为YES,这将允许视图再次位于状态栏下方。
如果问题不明确,请写一条评论,我会回答。
iOS如何知道要使用的UIScrollView?
iOS抓取ViewController视图中的第一个子视图,索引为0的子视图,如果它是UIScrollView
的子类,则将解释的属性应用于它。
当然,这意味着UITableViewController
默认有效(因为UITableView
是第一个视图)。
答案 1 :(得分:15)
不确定您是否正在使用故事板,但如果您正在使用,请使视图控制器从状态栏下方(并在底部栏上方)开始:
在IB中选择视图控制器, 在属性检查器中,取消选择“延伸边缘 - 顶部条形图”和“延伸边缘 - 底部条形图”。
答案 2 :(得分:10)
我正在使用故事板并使用上述建议,但我并不确定如何实现它。下面是一个简短的例子,它通过将推荐的解决方案放入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会导致故事板设计和模拟器之间出现差异
解决:
上面的代码适用,关闭自动调整。
答案 3 :(得分:5)
我通过添加此行解决了这个问题,但我的问题与UIView
有关,而不是UIScrollView
self.navigationController.navigationBar.translucent = NO;
答案 4 :(得分:2)
请记住这一点
automaticallyAdjustsScrollViewInsets
仅当某种滚动视图(表视图,集合视图,...)是
其他建议,即使它是第一个子视图也能正常工作,但视图层次结构中还有其他滚动视图。
编辑(扩展DIY)如果您想要类似的行为,即使您无法满足这些条件(例如,滚动视图下方有背景图像),您也可以手动调整滚动视图插图。但请不要把它设置为常数,如44或64甚至20,就像很多人建议的那样。你无法知道大小。可以有incall / gps / audio通知,导航栏不一定总是44点等。
我认为最好的解决方案是在didLayoutSubviews中使用layoutGuide length
:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentInset = UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: 0, right: 0)
scrollView.scrollIndicatorInsets = scrollView.contentInset
}
您可以以相同的方式使用bottomLayoutGuide。