iOS7之后的页面布局问题

iOS9 页面布局问题

前言

从iOS7之后,页面布局默认延伸到了手机界面的边缘。习惯了iOS7之前的布局,一时之间还有些适应不了,再加上之前从未使用AutoLayout。其实,从iPhone6出来之后,AutoLayout就应该强制的用起来了,可是公司一直在维护老项目,再者我也说了不算 T_T。

正文

界面结构分析

先看几个截图,随后分解iOS7之后的界面结构


图1 添加UITableView外观图
图2 添加UITableView结构图

说明:

  1. 图1 透过导航栏明显能看出底层是模糊的红色而并非绿色。红色一并穿透过状态栏一直延伸到界面的边界;
  2. 图2 根据标记,标记1 红色是UITableView的背景色,标记2 绿色是它上面的cell的背景色;
  3. UITableView上面添加了一个_UITableViewWrapperView视图,cell是添加在它上面的;并且它是从导航栏下方开始布局(空出了导航栏的位置);
  4. 标记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 ()

@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
默认情况测试图

情况一测试图

情况二测试图

情况三测试图

到这里要介绍的内容就完了,内容基本都是从头文件和结构图扒出来的,并参考了官方的文档进行了测试,如有不对的地方希望能指出来,我会虚心接受。谢谢。

你可能感兴趣的:(iOS7之后的页面布局问题)