Masonry 用法小结

根据给定宽度自适应文字大小

用label的两个属性就可以解决上述问题。
1.设置允许UILabel的宽度来自动适应字体大小:
label.adjustsFontSizeToFitWidth = YES;
2.设置允许文本显示的最小字体:
label.minimumScaleFactor = 0.1;

adjustsFontSizeToFitWidth这个属性的意思是根据UILabel的宽度来自动适应字体大小,但要注意的是,这个属性不会让字体变大,只会缩小,所以开始的时候,可以设置字体fontSize大一点。

Masonry 比例设置multipliedBy与dividedBy区别

multipliedBy是相对于自身比例(只能用于自身的比)dividedBy是相对于其他视图的比例(也可以用于自身的比)

multipliedBy是相当于算数中的“除以”,dividedBy相当于算数中的“除”,看以下具体操作:

 make.width.mas_equalTo(view1.mas_height).multipliedBy(0.3);
 make.left.mas_equalTo(self.view.mas_right).dividedBy(5);

自适应label高度和宽度

CompressionResistance 和 PriorityHuggingPrioritycontent
hugging 这个约束条件,会尽可能压缩视图,使其紧贴内容;
compression resistance 这个约束条件,会尽可能向外扩大视图,是内容尽可能不会被裁剪。

Content Compression Resistance = 不许挤我!
对,这个属性说白了就是“不许挤我”=。=
这个属性的优先级(Priority)越高,越不“容易”被压缩。也就是说,当整体的空间装不下所有的View的时候,Content Compression Resistance优先级越高的,显示的内容越完整。

Content Hugging = 抱紧!
这个属性的优先级越高,整个View就要越“抱紧”View里面的内容。也就是View的大小不会随着父级View的扩大而扩大。一般用于 UILabel 之类的控件。

设置 label 的 Hugging Priority,使其宽度跟文字内容一样宽
[label setContentHuggingPriority:UILayoutPriorityRequired
                                    forAxis:UILayoutConstraintAxisHorizontal];
设置 label 的 ContentCompressionResistance Priority,试其扛压缩能力最强
[label setContentCompressionResistancePriority:UILayoutPriorityRequired
                                                     forAxis:UILayoutConstraintAxisHorizontal];                                    

动态更新约束的优先级

平时使用Masonry时,一般会使用mas_updateConstraints方法来更新约束,不过该方法只能更新数值,并不会更新约束的优先级。

方式一

初始化后就立马修改的话(同一个Runloop循环内)并不会有变化,适用于初始化后晚一些再更新的情况。

@interface xxx ()
@property (nonatomic, strong) MASConstraint *constraint;
@end

@implementation xxx

- (void)setupConstraints {
    [self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        ......
        self.constraint = make.right.equalTo(self).priorityLow();
    }];
}

- (void)changePriority:(BOOL)isHigh {
    // 让约束失效(内部调用uninstall,从约束组内移除)
    [self.constraint deactivate]; 

    // 重新设置优先级
    if (isHigh) {
        self.constraint.priorityHigh();
    } else {
        self.constraint.priorityLow();
    }

    // 让约束生效(内部调用install,重新添加到约束组内)
    [self.constraint activate]; 

    // 刷新布局
    [self layoutIfNeeded];
}

@end

方式二:弱引用约束【推荐】

相当于重新创建约束(不是全部,重新创建的是想要更新的约束),适用各种情况,能立马更新。

@interface xxx ()
@property (nonatomic, weak) MASConstraint *constraint;
@end

@implementation xxx

- (void)setupConstraints {
    [self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        ......
        self.constraint = make.right.equalTo(self).priorityLow();
    }];
}

- (void)changePriority:(BOOL)isHigh {
    // 让约束失效(内部调用uninstall,从约束组内移除,由于当前约束是弱引用,没有被其他指针强引用着则会被系统回收)
    [self.constraint uninstall]; 

    // 重新创建约束(mas_updateConstraints 会把 block 内的约束添加到约束组内并生效)
    [self.nameLabel mas_updateConstraints:^(MASConstraintMaker *make) {
        if (isHigh) {
            self.constraint = make.right.equalTo(self).priorityHigh();
        } else {
            self.constraint = make.right.equalTo(self).priorityLow();
        }
    }];

    // 刷新布局
    [self layoutIfNeeded];
}

@end

iOS 12 UIStackView backgroundColor set

self.targetStackView = [UIStackView new];
    self.targetStackView.backgroundColor = [UIColor clearColor];
    self.targetStackView.layer.cornerRadius = 12;
    self.targetStackView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner | kCALayerMinXMaxYCorner | kCALayerMaxXMaxYCorner;
    self.targetStackView.axis = UILayoutConstraintAxisVertical;
    self.targetStackView.distribution = UIStackViewDistributionFill;
    self.targetStackView.alignment = UIStackViewAlignmentFill;
    [self.selectView addSubview:self.targetStackView];
    
    [self.targetStackView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(diver.mas_bottom).offset(20);
        make.left.mas_equalTo(12);
        make.right.mas_equalTo(-12);
    }];
    
    UIView *targetStackViewBGView = [UIView new];
    targetStackViewBGView.backgroundColor = [UIColor whiteColor];
    targetStackViewBGView.layer.cornerRadius = 12;
    targetStackViewBGView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner | kCALayerMinXMaxYCorner | kCALayerMaxXMaxYCorner;
    targetStackViewBGView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.targetStackView insertSubview:targetStackViewBGView atIndex:0];

动画

和一般动画不同的是,使用Masonry这样放入到动画的block中不能直接让动画生效,只是直接造成控件位移,经过尝试,应当添加如下操作

-(void)beginAnimate{
	//告知需要更改约束
    [self.view setNeedsUpdateConstraints];
    [UIView animateWithDuration:3 animations:^{
        [btn mas_updateConstraints:^(MASConstraintMaker *make) {
         make.right.mas_equalTo(view.mas_right).offset(-100);
        }];
        //告知父类控件绘制,不添加注释的这两行的代码无法生效
        [btn.superview layoutIfNeeded];
    }];
}

其中,[btn.superview layoutIfNeeded];必须添加在动画的block中,不然就会导致动画无法实现。