iOS界面布局的几种方式

iOS界面布局之一——使用代码进行布局

一、这是最简单的布局方式,在UI控件初始化时通过- (void)initWithFrame进行设置,或者在init之后在进行设置

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    UIView * view1 = [[UIView alloc]initWithFrame:CGRectMake(20, 40, 200, 200)];
    view1.backgroundColor=[UIColor redColor];
    UIView * view2 = [[UIView alloc]initWithFrame:CGRectMake(10, 10, 100, 100)];
    view2.backgroundColor=[UIColor greenColor];
    [view1 addSubview:view2];
    [self.view addSubview:view1];
}

效果是这样的(大家也应该能想的出来)
iOS界面布局的几种方式_第1张图片

当然了,这种情况下我们应该怎样做适配呢,在autoLayout没有出现之前,Apple提供的方法主要是autoresizing(在现在的xib/storyBoard里也能找到相应的设置)。

typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
    UIViewAutoresizingNone                 = 0,//默认
    UIViewAutoresizingFlexibleLeftMargin   = 1 << 0,//与父视图右边间距固定,左边可变
    UIViewAutoresizingFlexibleWidth        = 1 << 1,//视图宽度可变
    UIViewAutoresizingFlexibleRightMargin  = 1 << 2,//与父视图左边间距固定,右边可变
    UIViewAutoresizingFlexibleTopMargin    = 1 << 3,//与父视图下边间距固定,上边可变
    UIViewAutoresizingFlexibleHeight       = 1 << 4,//视图高度可变
    UIViewAutoresizingFlexibleBottomMargin = 1 << 5//与父视图上边间距固定,下边可变
};

二、使用AutoLayout进行页面布局

AutoLayout是Apple在iOS6之后提出的概念,和之前的autoresizing相比功能更加强大,也是Apple为了适配更多屏幕给出的解决方案,但是当时使用的人不是很多。在iOS7之后,AutoLayout更加完善,也逐渐被大家广为使用,现在,随着iPhone6,6Plus,7,7Plus的推出,AutoLayout布局方式也是大家的首选布局方式。

AutoLayout主要是通过原生枚举和一些属性设置来创建NSLayoutConstraint对象,主要使用NSLayoutConstraint类的如下方法:

+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;

下面给大家看一下原生的AutoLayout布局代码

UILabel * label = [[UILabel alloc]init];
    //使用代码布局 需要将这个属性设置为NO
    label.translatesAutoresizingMaskIntoConstraints = NO;
    label.backgroundColor = [UIColor redColor];
    //创建x居中的约束
    NSLayoutConstraint * constraintx = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
    //创建y居中的约束
    NSLayoutConstraint * constrainty = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
    //创建宽度约束
    NSLayoutConstraint * constraintw = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:100];
    //创建高度约束
    NSLayoutConstraint * constrainth = [NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:100];
    //添加约束之前,必须将视图加在父视图上
    [self.view addSubview:label];
    [self.view addConstraints:@[constraintx,constrainty,constrainth,constraintw]];

view:要添加约束的视图对象。
attr:要约束的对象属性,这个就是一些枚举,如

typedef NS_ENUM(NSInteger, NSLayoutAttribute) {
    NSLayoutAttributeLeft = 1,//左
    NSLayoutAttributeRight,//右
    NSLayoutAttributeTop,//上
    NSLayoutAttributeBottom,//下
    NSLayoutAttributeLeading,//起始边,类似左,只在某些从右向左排列的语言中和NSLayoutAttributeLeft有大区别
    NSLayoutAttributeTrailing,//结束边
    NSLayoutAttributeWidth,//宽度
    NSLayoutAttributeHeight,//高度
    NSLayoutAttributeCenterX,//x中心
    NSLayoutAttributeCenterY,//y中心
    NSLayoutAttributeBaseline,//基线
    NSLayoutAttributeLastBaseline = NSLayoutAttributeBaseline,
    NSLayoutAttributeFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0),

    //下面的属性是设置的边距 意义和上面类似 对应左,右等边距
    NSLayoutAttributeLeftMargin NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeRightMargin NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeTopMargin NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeBottomMargin NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeLeadingMargin NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeTrailingMargin NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeCenterXWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeCenterYWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),
    //无,后面会说应用场景
    NSLayoutAttributeNotAnAttribute = 0
};

大家可以看的出来,AutoLayout的原生代码是不是看着有点长(或者直接说有段乱),一眼根本看不出来当前的视图是加了哪些约束,哪种约束,何况在实际开发中,这样的代码我们可能会写很多很多。

所以,有一位国外的大神觉得这样写布局有点太难受了,根本不能给程序员最完美的体验,所以他决定自己写一个AutoLayout布局库,不仅让大家在几行代码下就能完成对UI控件的约束,而且还要简单易读,并且功能强大,之后——-一个在iOS开发界无人不知无人不晓的名字出现了,Masonry。

Masonry布局库轻量、简便、功能强大,可以满足任意布局的开发,而且到现在也一直在维护。

下面给大家看看代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    UILabel * label = [[UILabel alloc]init];
    [self.view addSubview:label];
    [label mas_makeConstraints:^(MASConstraintMaker *make) {
        make.center.equalTo(self.view);
        make.height.equalTo(@50);
        make.width.equalTo(@50);
    }];
    label.backgroundColor = [UIColor redColor];
}

大家看见了吗,你只需要在block里写上三局代码就可以是当前的label居中,设置宽度高度,并且一眼就能看出来你给的约束是什么,是给谁的约束。在开发中,我们需要删减约束,重置约束,更新约束等,这些在Masonry布局库中都有体现,也同样是非常简洁明了。

更新约束

[label mas_updateConstraints:^(MASConstraintMaker *make) {
        make.height.equalTo(@100);
        make.width.equalTo(@100);
    }];

重置约束

[label mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view.mas_left).offset(10);
        make.top.equalTo(self.view.mas_top).offset(100);
        make.height.equalTo(@100);
        make.width.equalTo(@100);
    }];

在添加具体约束的时候,我们不仅可以设置约束值的绝对相等关系,还可以设置一些值域的关系,具体如下:

//绝对相等
- (MASConstraint * (^)(id attr))equalTo;
//大于等于
- (MASConstraint * (^)(id attr))greaterThanOrEqualTo;
//小于等于
- (MASConstraint * (^)(id attr))lessThanOrEqualTo;

优先级

//手动设置一个优先级参数
- (MASConstraint * (^)(MASLayoutPriority priority))priority;
//优先级低
- (MASConstraint * (^)())priorityLow;
//优先级中等
- (MASConstraint * (^)())priorityMedium;
//优先级高
- (MASConstraint * (^)())priorityHigh;

运用中代码如下

[label mas_remakeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view.mas_left).offset(10);
        make.top.equalTo(self.view.mas_top).offset(100);
        make.height.equalTo(@100).priority(1000);
        make.width.equalTo(@100).priorityHigh();
    }];

在Masonry的使用中,介绍几个容易出问题的地方
1、首先为控件添加约束时,一定要先添加到父视图上,否则程序会崩溃。
2、在平时的使用中,Masonry中设置左边约束时,一般有make.left.equalTo(self.view.mas_left).offset(10);
或者make.leading.equalTo(self.view.mas_leading).offset(10);
同样右边约束时,有make.right.equalTo(self.view.mas_right).offset(10);
和make.trailing.equalTo(self.view.mas_trailng).offset(10);

有一点需要记住,在使用leading的时候对应的设置右边约束时一定要使用trailing,同样在使用left时,也要使用right来设置右边约束,相反也是一样,否则程序会进入崩溃,而且异常断点进入的地方也不会显示这个问题,很难发现是这个问题。

你可能感兴趣的:(iOS页面布局)