以编程方式更改UILabel中断布局上的约束

时间:2019-06-24 22:40:28

标签: ios objective-c nslayoutconstraint

我有一个带有两个约束的UILabel。我激活了一个约束,而另一个则禁用了。我有一个禁用第一个约束并激活第二个约束的按钮。然后,当第二次点击时,禁用第二约束并重新激活第一约束。第一次点击此按钮将按预期工作。 UILabel(包括受其约束的所有其他UILabel)将移动到另一个位置。但是,点击按钮将其移回时,布局会中断。 UILabel移至几乎以前的位置,但受其约束的所有其他UILabel保持原样,并且不会移回其原始位置。

这是处理激活约束的功能。

- (void)tapOnce:(UIGestureRecognizer *)gesture
{
    if (_constraintLabelOne.isActive) {
        [_constraintLabelOne setActive:NO];
        [_constraintLabelTwo setActive:YES];
    } else {
        [_constraintLabelTwo setActive:NO];
        [_constraintLabelOne setActive:YES];
    }
    [self layoutIfNeeded];
}

约束看起来像这样。

_constraintLabelOne = [NSLayoutConstraint constraintWithItem:myLabel
                                                                   attribute:NSLayoutAttributeTop
                                                                   relatedBy:NSLayoutRelationEqual
                                                                      toItem:topView
                                                                   attribute:NSLayoutAttributeBottom
                                                                  multiplier:1.0
                                                                    constant:6];
_constraintLabelTwo = [NSLayoutConstraint constraintWithItem:myLabel
                                                                   attribute:NSLayoutAttributeTop
                                                                   relatedBy:NSLayoutRelationEqual
                                                                      toItem:topView
                                                                   attribute:NSLayoutAttributeBottom
                                                                  multiplier:1.0
                                                                    constant:20];

第一次调用myLabel之后,其他约束为tapOnce的标签将停留在第二位置。在myLabel约束更新之后,为什么他们不回到初始位置?

我在屏幕快照中附有当前行为的图形。蓝色框代表topView。洋红色框代表myLabel。第一个屏幕是在调用tapOnce之前。中间屏幕是在调用tapOnce一次之后。两次调用tapOnce后,屏幕将显示在右侧。

enter image description here

2 个答案:

答案 0 :(得分:0)

我这样做的方式是将约束之一的priority设置得较低,这样它是“可选的”,例如UILayoutPriorityDefaultHigh,甚至更高,例如999。

然后您可以同时激活两个约束,并且优先考虑所需的约束。

要进行设置,请为默认状态设置所需的约束,并为按钮按下状态设置可选的约束。

您可以先激活两个约束,然后在按下按钮时,只需禁用(设置constraint.active = NO)所需的约束,另一个约束优先。再次按下按钮时,只需重新启用所需的约束即可。

答案 1 :(得分:0)

我知道了。发生的事情是UILabel的高度没有受到限制,因此当停用第二个约束并重新激活第一个约束时,高度会自动增加(请参见下图)。要解决此问题,我必须手动限制所有视图项的高度。如果有人有更好的解决方案,请发布它,因为我不希望手动为每个项目设置高度,因为这可能会导致布局在其他设备上中断。

enter image description here

更新

感谢siburb指出了UI元素的Content Hugging Priority属性。我问题的根源在于未设置此属性,这允许我的UILabel的高度扩展。解决方案是将此属性设置为750或更高的值。

[myLabel setContentHuggingPriority:750 forAxis:UILayoutConstraintAxisVertical];