在运行时以编程方式激活约束
Posted
技术标签:
【中文标题】在运行时以编程方式激活约束【英文标题】:activating constraints programmatically at runtime 【发布时间】:2017-11-01 06:26:49 【问题描述】:我想在运行时使用约束以编程方式更改视图的位置 我有以下观点安排
|
viewA
|
viewB
|
viewC
假设我将viewA
和topAnchor
约束设置为父视图边缘的顶部,viewB
将topAnchor
设置为viewA
等等viewC
我想在运行时更改这些视图在某些操作上的位置
|
viewA
|
viewC
|
viewB
我为viewB
存储了两个不同的约束,一个在viewA
的顶部,另一个在viewC
的顶部
viewBTopConstraints = viewB.topAnchor.constraint(equalTo: viewA.bottomAnchor, constant: TOP_SPACE)
newViewBTopConstraints = viewB.topAnchor.constraint(equalTo: viewC.bottomAnchor, constant: TOP_SPACE)
在我的切换操作方法中,我做了类似的事情
viewBTopConstraints?.isActive = false
newViewBTopConstraints?.isActive = true
这在第一次运行时有效,但第二次失败,在视图调试器中进一步调试时我发现它会创建重复的约束而不是更改原始约束。
【问题讨论】:
你应该只在第一次之后修改isActive
。
有没有办法实现这种行为?我想要的只是根据某些操作切换这些视图的位置,因为我已经使用约束以编程方式创建了我的视图,所以我无法弄清楚。
【参考方案1】:
您的要求听起来类似于我有一些基于横向或纵向更改的限制的应用程序。在那里我设置了三组约束:
那些总是是isActive = true
肖像中的isActive = true
那些isActive = true
在横向
诀窍是将后两者放入数组中,并在正确的时间激活/停用正确的数组。这是我的意思的sn-p:
var p = [NSLayoutConstraint]()
var l = [NSLayoutConstraint]()
////// portrait layout....
// pin info button above imageLayout, right justified
p.append(info.topAnchor.constraint(equalTo: margins.topAnchor, constant: 20.0))
p.append(info.trailingAnchor.constraint(equalTo: margins.trailingAnchor))
////// landscape layout....
// pin info button above buttons, right justified
l.append(info.topAnchor.constraint(equalTo: margins.topAnchor, constant: 20.0))
l.append(info.trailingAnchor.constraint(equalTo: margins.trailingAnchor))
请注意,我没有设置任何isActive = true
。我只是根据需要将东西附加到两个数组中。现在,在 viewWillLayoutSubviews()
- 根据您的需要,viewDidLayoutSubviews()
可能是更好的替代 - 您*激活/停用正确的数组:
NSLayoutConstraint.deactivate(l)
NSLayoutConstraint.deactivate(p)
if self.bounds.width > self.bounds.height
NSLayoutConstraint.activate(l)
else
NSLayoutConstraint.activate(p)
我发现使用单独的约束,设置isActive
,会大大增加发生冲突的风险。
【讨论】:
以上是关于在运行时以编程方式激活约束的主要内容,如果未能解决你的问题,请参考以下文章
在使用像 EF 这样的 ORM 时,是不是可以在运行时以编程方式创建新表?