Autoresizing与AutoLayout

作者: letaibai | 来源:发表于2016-04-17 13:23 被阅读82次

    Autoresizing

    • Autoresizing是在AutoLayout流行以前的一种屏幕适配技术,Autoresizing在当时很好的解决了子控件在父控件的位置问题,而且只需要很简单的设置即可.
    • 在xcode7.3中,使用Autoresizing时是需要先关掉AutoLayout的.
    • Autoresizing的设置
      • 通过storyboard
      • 选中要设置的控件,来到下图的位置

    在Autoresizing的选项后面有六根线,外面有四条(上下左右),里面有两条(宽高).在外面的4跟线中,如果在某个方向是是实线,代表距离该方向的距离固定.里面的两根线中,实线代表宽度或高度固定,虚线代表跟随父控件等比例拉伸.

    • 通过代码
    • 拿到设置的控件(以button为例)
        //设置伸缩左边间距(也就是控件的右边距是固定的)
        self.button.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
    

    如果设置多个方向的约束,可以在每个约束的后面以 | 运算符隔开.

        // 设置左/上伸缩,宽/高伸缩
        self.button.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight;
    

    下面是Autoresizing常用的代码约束:

     /*
        UIViewAutoresizingNone                 //无
        UIViewAutoresizingFlexibleLeftMargin   //左边伸缩
        UIViewAutoresizingFlexibleWidth        //宽度伸缩
        UIViewAutoresizingFlexibleRightMargin  //右边伸缩
        UIViewAutoresizingFlexibleTopMargin    //顶部伸缩
        UIViewAutoresizingFlexibleHeight       //高度伸缩
        UIViewAutoresizingFlexibleBottomMargin //底部伸缩
         */
    
    
    注意:Autoresizing只能解决控件在父控件之间的位置,不能解决子控件与其他控件之间的位置,所以Autoresizing的局限性比较大.
    

    AutoLayout

    • AutoLayout是苹果官方推出的一种自动布局技术,它很好的解决了Autoresizing所不能解决的问题,所以在现阶段屏幕匹配方面大家都喜欢使用AutoLayout.
    • AutoLayout的使用也比较简单,只需选中控件,设置位置宽高等约束,就决定了该控件在父控件中的布局.

    storyboard实现AutoLayout,选中要设置的空间,点击下图

    图1 图2
    图1用来设置对齐约束,图2用来设置位置(或与其他空间的间距)与宽高约束.
    设置完毕之后可以直接使用快捷键(command + option + =)来更新约束.

    代码实现AutoLayout
    在使用代码实现AutoLayout时,需要先将Autoresizing禁用,否则两者会引起冲突,使控件无法正常显示.

        //禁用button的Autoresizing功能
        self.button.translatesAutoresizingMaskIntoConstraints = NO;
    
        //自定义一个blueView
        UIView *blueView = [[UIView alloc] init];
        blueView.frame = CGRectMake(50, 100, 200, 200);
        blueView.backgroundColor = [UIColor blueColor];
        [self.view addSubview:blueView];
        blueView.translatesAutoresizingMaskIntoConstraints = NO;
        //创建宽度约束
        NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:200];
        //添加宽度约束
        [self.button addConstraint:widthConstraint];
    

    创建约束方法中的参数如下:

    +(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
    view1:需要添加约束的view
    attr1:view的属性(上下左右宽高)
    relation:与其他控件的关系(`<`=(NSLayoutRelationLessThanOrEqual),`=`(NSLayoutRelationEqual),`>=`(NSLayoutRelationGreaterThanOrEqual))
    view2:其他view(如不需要设置可填nil)
    attr2:其他view的属性(上下左右宽高,不设置可填`NSLayoutAttributeNotAnAttribute`)
    multiplier:乘数(填1是乘以view2本身的宽度)
    constant:需要加上的数值
    

    其中view的常用属性如下:

    typedef NS_ENUM(NSInteger, NSLayoutAttribute) {
        // 位置
        NSLayoutAttributeLeft ,
        NSLayoutAttributeRight,
        NSLayoutAttributeTop,
        NSLayoutAttributeBottom,
        NSLayoutAttributeLeading,
        NSLayoutAttributeTrailing,
        NSLayoutAttributeWidth,
        NSLayoutAttributeHeight,
        NSLayoutAttributeCenterX,
        NSLayoutAttributeCenterY,
        NSLayoutAttributeBaseline,
        NSLayoutAttributeLastBaseline = NSLayoutAttributeBaseline,
        NSLayoutAttributeFirstBaseline 
        // 间距
        NSLayoutAttributeLeftMargin,
        NSLayoutAttributeRightMargin, 
        NSLayoutAttributeTopMargin ,
        NSLayoutAttributeBottomMargin ,
        NSLayoutAttributeLeadingMargin ,
        NSLayoutAttributeTrailingMargin ,
        NSLayoutAttributeCenterXWithinMargins ,
        NSLayoutAttributeCenterYWithinMargins ,
        // 无属性
        NSLayoutAttributeNotAnAttribute = 0
    
    

    VFL代码模式,创建多个约束,需要分别创建vfl字符串,多次调用.

       //包装数字为NSNumber对象
       NSNumber *margin = @20;
       //定义VFL字符串
       NSString *vfl = @"H:|-margin-[button(width)]-margin-[textField(width)]-margin-|";
       //告诉vfl1中button是哪个控件,有多个参数用逗号隔开
       NSDictionary *views = @{@"button":button,@"textField":textField};
       //与上句等价,可写替代上句节约时间
       NSDictionary *views1 = NSDictionaryOfVariableBindings(button,textField);
       //告诉vfl中margin是哪个参数值,有多个参数用逗号隔开
       NSDictionary *metrics1 = NSDictionaryOfVariableBindings(margin);
       // 创建约束,返回值为数组
       NSArray *heightConstraints = [NSLayoutConstraint constraintsWithVisualFormat:vfl1 options:kNilOptions metrics:metrics1 views:views1];
       //添加数组约束
       [self.view addConstraints:heightConstraints];
    

    VFL模式的方法参数如下:

    + (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *, id> *)views;
    format:vfl字符串
    options:对齐样式(不用可传kNilOptions)
    metrics:变量参数(包装成字典对象传入)
    views:需要设置约束的view(包装成字典对象传入)
    
    VFL模式比纯代码实现AutoLayout方式能节约少许代码.开发中推荐使用第三方框架Masonry.

    相关文章

      网友评论

        本文标题:Autoresizing与AutoLayout

        本文链接:https://www.haomeiwen.com/subject/wxpolttx.html