XIB 自动布局

使用Storyboard动态修改约束

2018-01-04  本文已影响7人  第九号线

很好用的第三方约束框架“Masonry”,可以随时修改约束:

 [self.titleLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
      make.leading.equalTo(self.backButton.mas_trailing).offset(5);
      make.centerY.equalTo(self.backButton.mas_centerY);
      make.trailing.equalTo(self.shareButton.mas_leading).offset(-10);
 }];

现在,我们需要在Storyboard或xib中动态修改约束。

一、场景:

先看下最终效果:


F2FD1FA4-2E71-473C-BEC7-33AB3E5C5E19.png

标题与按钮之间的距离是变动的。根据状态的不同,标题的右边距可能在“查看”按钮的左边,可能在“重拍”按钮的左边。

二、遇到的坑

  1. 把约束设置为全局的私有变量;


    4A1A0AF1-ED9E-4F3B-9DFF-CEB5D1D45B89.png

    然并卵。因为我们的约束是在UITableView视图的Cell中。这个约束不能确定具体是UITableView的哪一个个cell。

  2. 边距设置在“查看”按钮左边。


    C4F2A30B-180C-4D4B-BC76-46301E27BECB.png

    如果“查看”按钮没有固定宽度:在需要隐藏“查看”的时候可以把“查看”按钮的标题置nil或“”字符串,这样标题右边距自然会移动到“拍摄”按钮的左边。

10B9C489-1FE1-4507-9E87-00D2D55AA74C.png

然而,现在“查看”按钮宽度固定,而且与“拍摄”按钮同宽。问题仍在。

  1. 在2坑的基础上引入。
    把“查看”按钮不设置为与“拍摄”按钮同宽,而是单独设置宽度约束:
    (1)在需要隐藏“查看”时,可以设置“查看”宽度约束的constant等于0;
    (2)在需要显示的时候,设置其宽度约束的constant等于“拍摄”按钮宽度。
    问题来了,如何找到UITableView的Cell中的“查看”按钮的宽度约束?

三、使用属性Identifier

使用约束(NSLayoutConstraint)对象的Identifier属性可以找到我们要找的约束。


7B5CF628-8B0B-4AAA-BA31-2190845097FB.png

(这里没有设置“查看”按钮宽度约束的Identifier。不过效果一样的,而且更简单。)

上代码:

if (examRoom.shotState) {
    ((UIButton *)[cell viewWithTag:15]).hidden = YES;  //上传按钮
    ((UIButton *)[cell viewWithTag:16]).hidden = NO;   //查看
    ((UIButton *)[cell viewWithTag:17]).hidden = NO;   //拍摄/重拍
    [((UIButton *)[cell viewWithTag:17]) setTitle:@"重拍" forState:UIControlStateNormal];
        
    [[self class] updateConstraint:[cell contentView] hidden:YES];
 }else {
    ((UIButton *)[cell viewWithTag:15]).hidden = YES;
    ((UIButton *)[cell viewWithTag:16]).hidden = YES;
    ((UIButton *)[cell viewWithTag:17]).hidden = NO;
    [((UIButton *)[cell viewWithTag:17]) setTitle:@"拍摄" forState:UIControlStateNormal];
        
    // 在cell.contentView中找约束,设置Constant
    [[self class] updateConstraint:[cell contentView] hidden:NO];
}
+ (void)updateConstraint:(UIView *)view hidden:(BOOL)hidden {
    NSArray *constraints = view.constraints;
    NSUInteger count = [constraints count];
    int index = 0;
    BOOL found = NO;
    while (!found && index < count) {
        NSLayoutConstraint *constraint = constraints[index];
        //遍历约束,找到Identifier=@“nameLabelConstraint”的约束
        if ([constraint.identifier isEqualToString:@"nameLabelConstraint"]) {
            found = YES;
            
            constraint.constant = hidden ? 60.0 : 0.0;
        }
        
        index++;
    }
}

四、总结

总结一下:

1,在选择使用Storyboard的时候要考虑清楚自己的需求。

Storyboard使用起来是非常方便,所见即所得。
但坑起来,也急死人。比如:多人用svn维护一个Storyboard,一不注意就会出现一堆冲突,很不容易解决,最后可能还得重做。
而且很多功Storyboard不能实现。比如:复杂动画,在UIScrollview中动态添加视图等等等。

2,Storyboard中,深挖NSLayoutConstraint每个属性的功能。

3,本文中的代码

传送门

上一篇 下一篇

猜你喜欢

热点阅读