iOS: 具有隐藏视图的布局约束
iOS: layout constraint with hidden views
假设我有两个底部对齐的视图:
V:[Label1]-10-[Label2]-20-|
Label1
和Label2
有10点间距,Label2
和底部有20点间距
现在,在某些情况下,我需要隐藏 Label2
,在这种情况下,我想要:
V:[Label1]-15-|
也就是说,Label2
被隐藏,Label1
到底部有 15 点间距。
我正在情节提要中设置它,我正在考虑使 15 点间距具有较低的优先级并根据需要隐藏 Label2
,但它似乎不起作用。
实现此目标的最佳方法是什么?
谢谢!
通过保持您提到的低优先级约束,我找到的较短的解决方案是:
@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!)
}
}
遗憾的是,隐藏视图只会影响 UIStackView
中的关联约束。这是因为 UIStackView
在隐藏视图时自动添加和删除约束。
解决这个问题的最佳方法是设置两组约束,adding/removing 每组都根据需要设置。我通常在创建这些约束
一个故事板,默认情况下不安装一组。然后,我为涉及的每个约束创建 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)
}
I'm setting this up in storyboard
基本上,你不能。您将不得不使用代码来管理这些约束。当您隐藏 Label2 时,还要换出第一组约束并换入第二组约束。当您显示 Label2 时,也换出第二组约束并换入第一组。这是完全标准的程序。
事实上,我有一个示例项目可以有效地展示如何准确地执行您所描述的操作:
如您所见,我们预先配置了视图 v2
存在和不存在的约束条件,并在我们删除或重新插入 v2
时交换它们。
如果在您的情况下合理,请使用 Label1 和 Label2 以及两个布局都处于活动状态来设置故事板。
对于 V:[Label1]-10-[Label2]-20-|
将 Label2 前导和尾随约束优先级设置为所需 (1000)
对于 V:[Label1]-15-|
将 Label1 尾随约束设置得较低(可能是 750)
然后,在适当的地方(viewDidLoad、layoutSubviews、updateConstraints 等),如果不需要 Label2,只需将其从其父视图中删除即可。
假设我有两个底部对齐的视图:
V:[Label1]-10-[Label2]-20-|
Label1
和Label2
有10点间距,Label2
和底部有20点间距
现在,在某些情况下,我需要隐藏 Label2
,在这种情况下,我想要:
V:[Label1]-15-|
也就是说,Label2
被隐藏,Label1
到底部有 15 点间距。
我正在情节提要中设置它,我正在考虑使 15 点间距具有较低的优先级并根据需要隐藏 Label2
,但它似乎不起作用。
实现此目标的最佳方法是什么?
谢谢!
通过保持您提到的低优先级约束,我找到的较短的解决方案是:
@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!)
}
}
遗憾的是,隐藏视图只会影响 UIStackView
中的关联约束。这是因为 UIStackView
在隐藏视图时自动添加和删除约束。
解决这个问题的最佳方法是设置两组约束,adding/removing 每组都根据需要设置。我通常在创建这些约束
一个故事板,默认情况下不安装一组。然后,我为涉及的每个约束创建 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)
}
I'm setting this up in storyboard
基本上,你不能。您将不得不使用代码来管理这些约束。当您隐藏 Label2 时,还要换出第一组约束并换入第二组约束。当您显示 Label2 时,也换出第二组约束并换入第一组。这是完全标准的程序。
事实上,我有一个示例项目可以有效地展示如何准确地执行您所描述的操作:
如您所见,我们预先配置了视图 v2
存在和不存在的约束条件,并在我们删除或重新插入 v2
时交换它们。
如果在您的情况下合理,请使用 Label1 和 Label2 以及两个布局都处于活动状态来设置故事板。
对于 V:[Label1]-10-[Label2]-20-|
将 Label2 前导和尾随约束优先级设置为所需 (1000)
对于 V:[Label1]-15-|
将 Label1 尾随约束设置得较低(可能是 750)
然后,在适当的地方(viewDidLoad、layoutSubviews、updateConstraints 等),如果不需要 Label2,只需将其从其父视图中删除即可。