动画中ProfileView高度约束不更新?约束添加方式疑问
问题解答
一、动画后高度无变化的核心原因
你的动画代码中查找高度约束的逻辑错误,导致根本没拿到要修改的约束:
if (constraint.firstAnchor == NSLayoutAttributeHeight) {
这里firstAnchor是NSLayoutAnchor类型的对象,而NSLayoutAttributeHeight是枚举值,两者类型完全不同,比较结果永远是NO,所以heightConstraint始终为nil。修改nil的constant自然不会有任何效果。
正确的判断方式应该是检查约束的firstAttribute:
if (constraint.firstAttribute == NSLayoutAttributeHeight) {
更稳妥的做法是将高度约束保存为实例变量,不用遍历查找,避免出错:
// 声明实例变量 @property (nonatomic, strong) NSLayoutConstraint *profileViewHeightConstraint; // 在addProfileView中赋值 _profileViewHeightConstraint = [NSLayoutConstraint constraintWithItem:_profileView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0 constant:160]; [NSLayoutConstraint activateConstraints:@[_profileViewHeightConstraint, widthConstraint, leftConstraint, topConstraint]]; // 动画中直接修改 [UIView animateWithDuration:0.3 animations:^{ _profileViewHeightConstraint.constant = isTop ? 64 : 160; [self.view layoutIfNeeded]; }];
二、是否应该将约束添加到父视图?
分两种情况:
- 视图的自身维度约束(如高度、宽度):可以添加到视图自身,也可以通过
activateConstraints自动处理。 - 跨视图约束(如子视图和父视图的left、top、width关联):必须添加到两个视图的共同父视图,否则约束会失效。
用activateConstraints时,系统会自动判断约束类型,将其添加到合适的视图上,无需手动指定。
三、[NSLayoutConstraint activateConstraints:]与[view addConstraints:]的区别
activateConstraints:(iOS8+):- 自动将约束添加到正确的容器视图:自身约束加给视图本身,跨视图约束加给共同父视图。
- 同时激活约束,无需额外调用
active = YES。 - 代码更简洁,不易出错。
addConstraints::- 需要手动指定约束添加到哪个视图,必须确保该视图是约束的合法容器(跨视图约束必须加共同父视图)。
- 仅添加约束,若要激活还需设置
constraint.active = YES(或在创建时用active:YES的API)。 - 手动管理容易出错,比如把跨视图约束加到子视图上,会导致约束失效。
内容的提问来源于stack exchange,提问作者Jackie Tom
相关产品推荐
相关产品推荐

