iOS 使用Masonry库做动画时报错?

1.实现过程:在VC viewDidload方法中 self.view addSubView:aLabel,viewWillLayoutSubviews 中使用Masonry添加label约束;另外界面有一个button,当当点击button时候做动画.

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.nameLabel];
}
-(UILabel*)nameLabel{
    
    if (!_nameLabel) {
        _nameLabel = [[UILabel alloc]initWithFrame:CGRectZero];
        _nameLabel.lineBreakMode = NSLineBreakByTruncatingTail;
        _nameLabel.text = @"王二小";
        _nameLabel.backgroundColor = [UIColor greenColor];
        _nameLabel.textAlignment = NSTextAlignmentLeft;
    }
    
    return _nameLabel;
}

-(void)viewWillLayoutSubviews{
    [self addCContraints];
}

-(void)addCContraints{
    
    [self.nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.view.mas_left).offset(10);
        make.top.equalTo(self.view.mas_top).offset(10);
    }];
}


//点击button的响应时间.

-(void)animationAction{
    
    ///设置长度.
    [self.nameLabel mas_updateConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(-30);
    }];

    [UIView animateWithDuration:0.3 animations:^{
        [self.nameLabel.superview layoutIfNeeded];
    }];
    
}

**"约束冲突信息:"**

2017-08-09 22:24:47.196344 NSString[13501:3837010] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
(
    "<MASLayoutConstraint:0x1700b4640 UILabel:0x10dd09830.left == UIView:0x10de0c4d0.left - 30>",
    "<MASLayoutConstraint:0x1700b5ae0 UILabel:0x10dd09830.left == UIView:0x10de0c4d0.left + 10>"
)

Will attempt to recover by breaking constraint 
<MASLayoutConstraint:0x1700b5ae0 UILabel:0x10dd09830.left == UIView:0x10de0c4d0.left + 10>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

跟了下Masonry执行过程也没发现什么问题.有朋友遇到过这种问题么?感谢在先.
阅读 3.7k
2 个回答

首先, self.View显示时会调用viewWillLayoutSubviews,然后点击button时,执行animateWithDuration, 由于修改了约束, 控制器还会执行viewWillLayoutSubviews一次.
也就是说从显示到点击, 一共viewWillLayoutSubviews会执行两次.

虽然mas_updateConstraints不会添加新的left约束, 但是由于mas_updateConstraints执行后再调用layoutIfNeeded, 那么self.nameLabel内部会有left约束=-30(mas_updateConstraints)left约束=View+10(layoutIfNeeded调用viewWillLayoutSubviews再次添加)同时存在, 所以系统报约束重复警告!

不要在viewWillLayoutSubviews上执行添加约束方法, 因为会执行多次,可以改在viewDidLoad上添加.

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addSubview:self.nameLabel];
    [self addCContraints];
}

报错不是说的很清楚了嘛。
UILabel.left == UIView.left - 30
UILabel.left == UIView.left + 10

-->

调用时机 有问题

  • (void)viewWillLayoutSubviews — 
    Called to notify the view controller that its view is about to layout its subviews. This method is called every time the frame changes like for example when rotate or it’s marked as needing layout. It’s the first step where the view bounds are final. If you are not using autoresizing masks or constraints and the view size changes you probably want to update the subviews here.

iOS UIViewController lifecycle

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进