iOS9 页面布局问题
前言
从iOS7之后,页面布局默认延伸到了手机界面的边缘。习惯了iOS7之前的布局,一时之间还有些适应不了,再加上之前从未使用AutoLayout。其实,从iPhone6出来之后,AutoLayout就应该强制的用起来了,可是公司一直在维护老项目,再者我也说了不算 T_T。
正文
界面结构分析
先看几个截图,随后分解iOS7之后的界面结构
图1 添加UITableView外观图 图2 添加UITableView结构图
说明:
- 图1 透过导航栏明显能看出底层是模糊的红色而并非绿色。红色一并穿透过状态栏一直延伸到界面的边界;
- 图2 根据标记,标记1 红色是UITableView的背景色,标记2 绿色是它上面的cell的背景色;
- UITableView上面添加了一个_UITableViewWrapperView视图,cell是添加在它上面的;并且它是从导航栏下方开始布局(空出了导航栏的位置);
- 标记3 导航栏却并没有延伸到边界,导航栏里面添加的_UINavgationBarBackground视图却延伸到了边界。而此视图上面添加了UIImageView和视图是一样大的。(上面还添加了视图_UIBackdropView,其实就是push到下一个页面显示出来的Back按钮,这里暂时不说)。
到这里,界面的布局其实大概已经说清楚了;关于给导航栏设置背景色或是背景图片参考我的上一篇文章,后面说一下UITableView上面的cell怎么设置会空出导航栏的位置,怎么设置会从最顶端开始显示。
iOS7 新添属性介绍
iOS7之后,弃用了之前用于全屏显示的属性wantsFullScreenLayout,而改用
edgesForExtendedLayout,并添加了其他2个用于方便AutoLayout布局UIScrollView及其继承控件的属性
@property(nonatomic,assign) UIRectEdge edgesForExtendedLayout NS_AVAILABLE_IOS(7_0); // Defaults to UIRectEdgeAll
@property(nonatomic,assign) BOOL extendedLayoutIncludesOpaqueBars NS_AVAILABLE_IOS(7_0); // Defaults to NO, but bars are translucent by default on 7_0.
@property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets NS_AVAILABLE_IOS(7_0); // Defaults to YES
解释:
- edgesForExtendedLayout:类型为UIRectEdge,有以下值可供选择,默认值为UIRectEdgeAll,即:四边都和父视图贴合。
typedef NS_OPTIONS(NSUInteger, UIRectEdge) {
UIRectEdgeNone = 0,
UIRectEdgeTop = 1 << 0,
UIRectEdgeLeft = 1 << 1,
UIRectEdgeBottom = 1 << 2,
UIRectEdgeRight = 1 << 3,
UIRectEdgeAll = UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeBottom | UIRectEdgeRight
} NS_ENUM_AVAILABLE_IOS(7_0);
- extendedLayoutIncludesOpaqueBars:默认值为NO(看有些文章说默认值是YES,不知道是不是XCode7之后苹果修改了这个值,以前到没怎么在意),这个属性在状态栏不透明的状态下才生效。也就是说,一般使用这个属性应该这样使用:
// 状态栏不透明(必须设置,并且为NO)
self.navigationController.navigationBar.translucent = NO;
// 视图延伸不考虑透明的Bars(这里包含导航栏和状态栏)
// 意思就是延伸到边界
self.extendedLayoutIncludesOpaqueBars=YES;
// 意思就是空出导航栏位置
// self.extendedLayoutIncludesOpaqueBars=NO;
- automaticallyAdjustsScrollViewInsets:默认值为YES,如果是UIScroolview以及继承自它的控件,默认值YES是设置它的Insets为自适应。这里自适应其实就是空出状态栏的位置。
其他
添加UIView视图时,除了不牵扯到automaticallyAdjustsScrollViewInsets属性外,其他设置与上面类似。
最后
贴出完整代码和设置前后的效果图:
#import "ViewController.h"
@interface ViewController ()<UITableViewDataSource>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//1 默认情况(导航栏透明,cell自适应:空出导航栏位置开始布局)
//
//2 情况一(导航栏透明,cell禁止自适应:从UITaleView顶端开始布局)
//self.automaticallyAdjustsScrollViewInsets=NO;
//3 情况三(cell禁止自适应,导航栏不透明,空出导航栏位置开始布局)
//self.navigationController.navigationBar.translucent = NO;
//self.extendedLayoutIncludesOpaqueBars=NO;
//self.automaticallyAdjustsScrollViewInsets=NO;
//4 情况四(cell禁止自适应,导航栏不透明,从UITaleView顶端开始布局)
//self.navigationController.navigationBar.translucent = NO;
//self.extendedLayoutIncludesOpaqueBars=YES;
//self.automaticallyAdjustsScrollViewInsets=NO;
//5 情况五(导航栏透明,cell禁止自适应,extendedLayoutIncludesOpaqueBars的设置是无效的)
UITableView * tableVeiw = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.view.frame)) style:UITableViewStylePlain];
tableVeiw.backgroundColor = [UIColor redColor];
tableVeiw.dataSource = self;
tableVeiw.rowHeight = 80;
[self.view addSubview:tableVeiw];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * cellID = @"Identifider";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
}
cell.backgroundColor = [UIColor greenColor];
cell.textLabel.text = @"测试页面";
return cell;
}
@end
默认情况测试图
情况一测试图
情况二测试图
情况三测试图
到这里要介绍的内容就完了,内容基本都是从头文件和结构图扒出来的,并参考了官方的文档进行了测试,如有不对的地方希望能指出来,我会虚心接受。谢谢。
网友评论