iOS:具有隐藏视图的布局约束

时间:2018-01-30 00:30:24

标签: ios uiview autolayout nslayoutconstraint

假设我有两个视图与底部对齐:

V:[Label1]-10-[Label2]-20-|

Label1Label2之间有10个点间距,Label2和底部之间有20个点。

现在,在某些情况下,我需要隐藏Label2,在这种情况下,我想要:

V:[Label1]-15-|

也就是说,隐藏Label2后,Label1的底部间距为15个点。

我在故事板中设置了这个,我正在考虑使15点间距的优先级较低,并根据需要隐藏Label2,但它似乎不起作用。

实现这一目标的最佳方法是什么?

谢谢!

4 个答案:

答案 0 :(得分:1)

通过保持您提到的低优先级限制,我发现的更短的解决方案是:

@IBOutlet weak var view2: UIView!
var constraints: [NSLayoutConstraint]? = nil

func foo() {
    if needsToHideView2 {
        constraints = view2.constraints
        NSLayoutConstraint.deactivate(view2.constraints)
    }
    if needsToShowView2 {
        NSLayoutConstraint.activate(constraints!)
    }
}

答案 1 :(得分:0)

不幸的是,隐藏视图只会影响UIStackView中的相关约束。这是因为UIStackView在隐藏视图时会自动添加和删除约束。

解决此问题的最佳方法是使用两组约束并根据需要添加/删除每个集合。我通常会创建这些约束 故事板,默认情况下没有安装一套。然后,我为每个约束创建IBOutlets,以便我可以在代码中轻松引用它们:

if button.isHidden {
    self.view.addConstraint(self.hiddenConstraint)
    self.view.removeConstraint(self.visibleConstraint)      
} else {
    self.view.removeConstraint(self.hiddenConstraint)
    self.view.addConstraint(self.visibleConstraint)
}

答案 2 :(得分:0)

  

我在故事板中设置了这个

基本上,你不能。您将不得不使用代码来管理这些约束。隐藏Label2时,还要换掉第一组约束并交换第二组约束。当您显示Label2时,还要换掉第二组约束并交换第一组约束。这是完全标准的程序。

事实上,我有一个示例项目,可以有效地显示如何完成您所描述的内容:

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/master/bk2ch01p032constraintSwapping/ConstraintSwapping/ViewController.swift

正如您所看到的,我们事先配置了视图v2何时出现以及何时不存在时的约束,并在我们移除或重新插入v2时将其交换。

答案 3 :(得分:0)

如果您的情况合理,请同时设置Label1和Label2并同时激活两个布局。

对于V:[Label1]-10-[Label2]-20-|,将Label2前后约束优先级设置为必填(1000)

对于V:[Label1]-15-|,将Label1尾随约束设置得较低(也许是750)

然后,在不需要的地方(viewDidLoad,layoutSubviews,updateConstraints等),将Label2从其超级视图中删除。