问题场景:网上复制粘贴了一串代码,出现了view高度不等于MainScreen高度。
- 基础尝试
结果无效
// 基础尝试 无效
open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.view.frame = CGRect(x: 0, y: 0, width: SCREENW, height: SCREENH)
}
open override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.view.frame = CGRect(x: 0, y: 0, width: SCREENW, height: SCREENH)
}
效果如下
- 进阶尝试
有效果但是不完美,每次进入页面viewDidLayoutSubviews都会被调起5次,并且最后一次产生效果,会出现屏幕延迟刷新的感觉,体验不好。
open override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
print(self.view.frame)
self.view.frame = CGRect(x: 0, y: 0, width: SCREENW, height: SCREENH)
}
- 最后挣扎
找到祸乱之源,删之。效果不错。
// 祸乱之源
if self.responds(to: #selector(setter: edgesForExtendedLayout)) {
self.edgesForExtendedLayout = []
}
self.extendedLayoutIncludesOpaqueBars = false
- 祸乱剖析
controller初始化并未对view进行处理,这时view的属性为nil。之后一旦访问view属性,只要为nil,则开始加载view。如果有nib,则从nib自动加载。如果没有则动用Controller的loadview方法。此时在loadview里,若使用[super loadview]; 则会更具window的大小,创建一个默认的view。如果要自定义view,则不要去调这行代码。之后view属性设置好以后,则会调用viewdidload;而viewWillAppear和viewDidApper在addsubview的时候调用
-[UIView addSubview:]
-[_setViewAppearState:isAnimating:]
-[layoutSubviews]
-[viewDidAppear]
edgesForExtendedLayout
指定边缘要延伸的方向,iOS7鼓励全屏布局模式,默认值是UIRectEdgeAll。
没用过的人可能不知道这是什么意思,举例假如我们页面上面有导航了,这个时候页面起始点仍然从状态栏上方开始计算,举例子你一个视图要全屏显示就要设置成:
CGRectMake(0, 64, SCREENW, self.view.frame.size.height - 64)
extendedLayoutIncludesOpaqueBars
延伸视图包含不包含不透明的Bar,是用来指定导航栏是透明的还是不透明,iOS7中默认是YES,当滚动页面的时候我们隐约能在导航栏下面看到我们页面的视图。
但是当我们设置一张不透明的图片作为导航栏背景时,该属性就会变成NO,这样不透明以后我们可以人为设置成YES达到延伸至导航栏的效果:
只有到两个属性都设置成可以延伸时,页面起始点才会从状态栏也就是屏幕最左上角开始
if self.responds(to: #selector(setter: edgesForExtendedLayout)) {
self.edgesForExtendedLayout = []
}
self.extendedLayoutIncludesOpaqueBars = false
参考文章
1.iOS7之后的适配属性讲解edgesForExtendedLayout、extendedLayoutIncludesOpaqueBars等