使用AutoLayout约束隐藏UIView

Ben*_*ard 29 uiview ios autolayout nslayoutconstraint

我有时会想要从布局中删除子视图.它不仅应该被隐藏,而且不应该被视为视图"流"的一部分,可以这么说.一个例子:

在此输入图像描述

我正在寻找一种策略来以编程方式隐藏橙色视图.框的布局及其内容是通过自动布局进行的.有两点需要注意:

  • 橙色框根据内容定义其垂直高度,以及边距的一些顶部/底部偏移.因此,将标签的文本设置为nil只会将视图"缩小"到它的内部边距,它的高度不会为0.
  • 同样,三个方框之间的垂直间距意味着即使橙色框的高度为0,红色和黄色之间的间隙也将是所需的两倍.

可能的解决方案

我最好的建议是在橙色框中添加一个约束,将其高度设置为0.为此,我需要对橙色框内的所有垂直约束使用非必需的优先级.同时,容器应更新用于分隔框的约束的常量.我不太喜欢这种方法,因为橙色盒子类正在定义它的内部约束,并考虑到它的superview的行为.如果橙色框视图反而暴露了一个"崩溃"方法,它本身就添加了0高度约束,也许我可以忍受它.

有更好的方法吗?

rde*_*mar 69

您可以通过在较低优先级的黄色和红色视图之间添加额外约束,并调整代码中的优先级来实现此目的.

在此输入图像描述

短虚线约束(orangeToRedCon是插座)的优先级为999(您不能将所需的优先级更改为非必需的,因此这就是为什么它不是1000).长虚线约束(yellowToRedCon)的优先级为500,常量为20.在代码中,您可以隐藏橙色视图,并交换这些优先级,这将使黄色视图向上移动到您所拥有的任何值设置为yellowToRedCon的常量值.

-(void)changePriorities {
    self.yellowToRedCon.priority = 999;
    self.orangeToRedCon.priority = 500;
    [UIView animateWithDuration:.5 animations:^{
        self.orangeView.alpha = 0;
        [self.view layoutIfNeeded];
    }];
}
Run Code Online (Sandbox Code Playgroud)

此方法不需要对橙色视图的高度进行任何更改.

  • 小心,否则你会得到这个错误:''不支持将优先级从需要变为不安装约束(反之亦然).你通过了优先级1000,现有的优先级是250.'`这些都不能超过1000. (7认同)
  • 到目前为止最好的解决方案,因为我甚至不必更新橙色视图的标签文本.整个视图从布局中被隐藏和忽略,这在语义上完全是我提出的问题. (3认同)
  • 只要你处理优先级<1000,这是最好的解决方案. (3认同)

fab*_*abb 14

在iOS 9中,您可以使用UIStackView它.旧版本还有polyfill:TZStackViewOAStackView