很好用的第三方约束框架“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中动态修改约束。
一、场景:
先看下最终效果:
标题与按钮之间的距离是变动的。根据状态的不同,标题的右边距可能在“查看”按钮的左边,可能在“重拍”按钮的左边。
二、遇到的坑
-
把约束设置为全局的私有变量;
然并卵。因为我们的约束是在UITableView视图的Cell中。这个约束不能确定具体是UITableView的哪一个个cell。
-
边距设置在“查看”按钮左边。
如果“查看”按钮没有固定宽度:在需要隐藏“查看”的时候可以把“查看”按钮的标题置nil或“”字符串,这样标题右边距自然会移动到“拍摄”按钮的左边。
然而,现在“查看”按钮宽度固定,而且与“拍摄”按钮同宽。问题仍在。
- 在2坑的基础上引入。
把“查看”按钮不设置为与“拍摄”按钮同宽,而是单独设置宽度约束:
(1)在需要隐藏“查看”时,可以设置“查看”宽度约束的constant等于0;
(2)在需要显示的时候,设置其宽度约束的constant等于“拍摄”按钮宽度。
问题来了,如何找到UITableView的Cell中的“查看”按钮的宽度约束?
三、使用属性Identifier
使用约束(NSLayoutConstraint)对象的Identifier属性可以找到我们要找的约束。
(这里没有设置“查看”按钮宽度约束的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每个属性的功能。
- Constant:边距具体数字。
- Priority:优先级。
- Multiplier:宽高比例。
- Identifier:标识符。
等等。