iOS约束布局

作者: 会武的锄头 | 来源:发表于2016-10-10 18:06 被阅读857次

    translatesAutoresizingMaskIntoConstraints属性:

    如果你定义的view想用autolayout,就将translatesAutoresizingMaskIntoConstraints = NO
    如果你使用的不是autolayout,就将translatesAutoresizingMaskIntoConstraints = YES
    

    Masonry

    方法

    >1.mas_makeConstraints 只负责新增约束 Autolayout不能同时存在两条针对于同一对象的约束 否则会报错 
    - (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block;
    
    >2.mas_updateConstraints 针对上面的情况 会更新在block中出现的约束 不会导致出现两个相同约束的情况
    - (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block;
    
    >3.mas_remakeConstraints 则会清除之前的所有约束 仅保留最新的约束
    - (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block;
    

    属性

    Masonry属性.jpg

    @property (nonatomic, strong, readonly) MASConstraint *(^attributes)(MASAttribute attrs);
    @property (nonatomic, strong, readonly) MASConstraint *edges;
    @property (nonatomic, strong, readonly) MASConstraint *size;
    @property (nonatomic, strong, readonly) MASConstraint *center;

    MASConstraint常用属性

    //乘以
    - (MASConstraint * (^)(CGFloat multiplier))multipliedBy;
    //除以
    - (MASConstraint * (^)(CGFloat divider))dividedBy;
    //优先级
    - (MASConstraint * (^)(MASLayoutPriority priority))priority;
    

    使用注意:

    1.mas_equalTo:是在对象中使用的
    2.如果是自动包装,使用mas_equalTo(100),使用equalTo(@100)

    3.size也是可以直接赋值的

    UIView 中更新布局的相关方法:

    Laying out SubViews
    - layoutSubviews() //不要直接调用,如果需要强制更新布局,调用下面的 setNeedsLayout()
    - setNeedsLayout() //标记布局需要在下一个周期更新
    - layoutIfNeeded()  //立刻更新布局
    Triggering Auto Layout
    - setNeedsUpdateConstraints() //标记约束需要在稍后更新,系统会调用下面的 updateConstraints()方法,修改多个约束后调用该方法批量更新有助于提升性能
    - updateConstraints() //更新调用该方法的视图的约束
    - updateConstraintsIfNeeded() //更新调用该方法的视图以及其子视图的约束
    

    view之间的优先级关系

    equalTo  <=======>   NSLayoutRelationEqual   等于
    lessThanOrEqualTo   <======>  NSLayoutRelationLessThanOrEqual   小于或等于
    greaterThanOrEqualTo <=======>  NSLayoutRelationGreaterThanOrEqual  大于或等于
    例子:priorityLow()是提高优先级
      [self.growingButton updateConstraints:^(MASConstraintMaker *make) {
            make.center.equalTo(self);
            make.width.equalTo(@100).priorityLow();
            make.height.equalTo(@(self.buttonSize.height)).priorityLow();
            make.width.lessThanOrEqualTo(self);
            make.height.lessThanOrEqualTo(self);
        }];
    

    调试约束的小帮手,key的妙用

    当约束冲突发生的时候,我们经常为找不到是哪个View冲突的而烦恼,这一堆View是个什么东西呀?

    "<MASLayoutConstraint:0x7f8de483fb10 UIView:0x7f8de2f53870.left == UIView:0x7f8de2f586c0.left>",
    "<MASLayoutConstraint:0x7f8de4818b50 UIView:0x7f8de2f53870.right == UIView:0x7f8de2f586c0.right>",
    Will attempt to recover by breaking constraint 
    <MASLayoutConstraint:0x7f8de4818870 UIView:0x7f8de2f53870.width == 100>
    

    这时候我们可以设置View的key:

    self.view.mas_key = @"self.view";
    view1.mas_key = @"view1";
    
    `Masonry也提供了批量设置的宏`MASAttachKeys:
    MASAttachKeys(self.view,view1);
    

    设置之后再看一下,哈哈,现在好多了。可以清晰的知道是哪个view了

    "<MASLayoutConstraint:0x7fcd98d17c40 UIView:view1.left == UIView:self.view.left>",
    "<MASLayoutConstraint:0x7fcd98d2b2c0 UIView:view1.right == UIView:self.view.right>",
    
    Will attempt to recover by breaking constraint 
    <MASLayoutConstraint:0x7fcd98d2adb0 UIView:view1.width == 100>
    

    常见问题

    cell中设置一个view,在layoutSubviews方法中并没有获取到该View的真实高度,可以在方法中让它先更新布局。

    - (void)layoutSubviews{
        [super layoutSubviews];
        [self.contentView setNeedsLayout];
        [self.contentView layoutIfNeeded];
    }
    

    如果是在控制器中需要知道一个控件的frame,在viewDidLayoutSubviews进行赋值

    - (void)viewDidLayoutSubviews{
        [super viewDidLayoutSubviews];
    }
    

    相关文章

    UIView的setNeedsLayout,layoutIfNeeded等方法介绍

    相关文章

      网友评论

        本文标题:iOS约束布局

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