Masonry使用总结

方法requiresConstraintBasedLayout的含义

方法
+ (BOOL)requiresConstraintBasedLayout NS_AVAILABLE_IOS(6_0);
API说明

/* constraint-based layout engages lazily when someone tries to use it (e.g., adds a constraint to a view). If you do all of your constraint set up in -updateConstraints, you might never even receive updateConstraints if no one makes a constraint. To fix this chicken and egg problem, override this method to return YES if your view needs the window to use constraint-based layout.
*/

解释:
意思是说基于约束的布局是懒加载的,只有在添加的约束的情况下,系统才会自动调用- (void)updateConstraints方法。如果吧所有的约束条件都放在- (void)updateConstraints中,系统就不会知道你的布局方式是基于约束的,重写+ (BOOL)requiresConstraintBasedLayout NS_AVAILABLE_IOS(6_0);方法并返回YES,就是明确的告诉系统采取的是基于约束的布局,从而保证系统一定会调用- (void)updateConstraints方法。

添加调试Key

方便发现发生冲突的约束,设置key

  • 给View添加
greenView.mas_key = @"greenView";
redView.mas_key = @"redView";

或者使用方法

//OR you can attach keys automagically like so:
MASAttachKeys(greenView, redView, blueView, superview);
  • 给指定constaints设置key
make.edges.equalTo(@1).key(@"ConflictingConstraint"); //composite constraint keys will be indexed

这样如果约束出现问题,可以很明确的找出是哪个约束。

关于UILable的自适应

    UILabel *bottomLable = [[UILabel alloc]init];
    bottomLable.numberOfLines = NSUIntegerMax;
    bottomLable.lineBreakMode = NSLineBreakByWordWrapping;
    bottomLable.textColor = [UIColor redColor];
    bottomLable.text = @"Bacon ipsum dolor sit amet spare ribs fatback kielbasa salami, tri-tip jowl pastrami flank short loin rump sirloin. Tenderloin frankfurter chicken biltong rump chuck filet mignon pork t-bone flank ham hock.";
    bottomLable.preferredMaxLayoutWidth = 20;
    [self addSubview:bottomLable];
    
    [bottomLable mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.bottom.equalTo(self).offset(-10);
    }];

记得要设置preferredMaxLayoutWidth属性。

如果需要设置动态的宽度

- (void)layoutSubviews {
    [super layoutSubviews];

    // for multiline UILabel's you need set the preferredMaxLayoutWidth
    // you need to do this after [super layoutSubviews] as the frames will have a value from Auto Layout at this point

    // stay tuned for new easier way todo this coming soon to Masonry

    CGFloat width = CGRectGetMinX(self.shortLabel.frame) - kPadding.left;
    width -= CGRectGetMinX(self.longLabel.frame);
    self.longLabel.preferredMaxLayoutWidth = width;

    // need to layoutSubviews again as frames need to recalculated with preferredLayoutWidth
    [super layoutSubviews];
}

对多个视图进行相同的操作

使用Array的分类中实现的方法来实现

[self.array updateConstraints:^(MASConstraintMaker *make) {
        make.baseline.equalTo(self.mas_centerY).with.offset(self.offset);
    }];

几个相同的视图的规律排列

两种方法

  • 中间空余部分确定
[arr mas_distributeViewsAlongAxis:MASAxisTypeVertical withFixedSpacing:20 leadSpacing:5 tailSpacing:5];
            [arr makeConstraints:^(MASConstraintMaker *make) {
                make.left.equalTo(@0);
                make.width.equalTo(@60);
            }];
  • 视图的Size确定
[arr mas_distributeViewsAlongAxis:MASAxisTypeHorizontal withFixedItemLength:30 leadSpacing:200 tailSpacing:30];
            [arr makeConstraints:^(MASConstraintMaker *make) {
                make.top.equalTo(@60);
                make.height.equalTo(@60);
            }];

处理带有UINavigationbar或者UITabbar时屏幕旋转时改变的问题

使用mas_topLayoutGuide属性来自动动态获取

[topView makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.mas_topLayoutGuide);
        make.left.equalTo(self.view);
        make.right.equalTo(self.view);
        make.height.equalTo(@40);
    }];

动画的实现

首先将动画之后的状态设置,然后调用[self layoutIfNeeded];

    int padding = invertedInsets ? 100 : self.padding;
    UIEdgeInsets paddingInsets = UIEdgeInsetsMake(padding, padding, padding, padding);
    for (MASConstraint *constraint in self.animatableConstraints) {
        constraint.insets = paddingInsets;
    }

    [UIView animateWithDuration:1 animations:^{
        [self layoutIfNeeded];
    } completion:^(BOOL finished) {
    }];

推荐阅读更多精彩内容