使用可视化格式语言更改NSLayoutConstraints的方向的正确方法

时间:2015-09-06 16:45:38

标签: ios swift nslayoutconstraint visual-format-language

我有单独的NSLayoutConstraints数组使用视觉格式化字符串构建,我想用于纵向和横向方向。我尝试了两种方法在两者之间切换:激活/停用它们,以及添加/删除它们。

激活/去激活:

portaitConstraints.forEach {
    $0.active = false
}
landscapeConstraints.forEach {
    $0.active = true
}

添加/删除:

self.view.removeConstraints(portraitConstraints)
self.view.addConstraints(landscapeConstraints)

这两种方法似乎都运行良好并且按预期运行,但是我使用activate / deactivate方法得到以下运行时错误:

Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. 
Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 

这有共同的模式吗?如果错误行为符合预期,我可以安全地忽略错误吗?一种方法与另一种方法的开销是否更高?我认为只需翻转" active"我希望活动的属性与反复添加和删除视图中的约束的属性。

或者这只是一种愚蠢的方式,我需要做一些像直接改变NSLayoutAttributes的事情?

2 个答案:

答案 0 :(得分:1)

您可能存在布局模糊,某些约束可能会相互冲突。如果您没有为设置约束的视图设置translatesAutoresizingMaskIntoConstraints = NO,通常会发生这种情况。控制台为您提供了冲突约束的列表,您应该解决布局歧义,因为它可能导致错误的布局。它不是致命的,但如果你想要一个好看的应用程序 - 你需要看一下它。

WWDC 2015有一个很棒的视频,Mysteries of Auto Layout, Part 2WWDC2012, Auto Layout by Example,描述了如何快速找到冲突的约束并解决它。这些也是了解整个汽车布局的精彩视频。 WWDC还有更多视频,例如Best Practices for Mastering Auto LayoutTaking Control of Auto Layout in Xcode 5或{{3}},其中包含大量有关自动布局的信息。

答案 1 :(得分:0)

我有一个类似的问题,水平显示约束在垂直显示上无法满足,而垂直显示约束在水平显示上无法满足。关键似乎是在正确的时间停用和激活正确的约束。这是我的操作方法,最终避免了错误:

override func viewWillLayoutSubviews() {
  if view.bounds.size.height >= view.bounds.size.width {
    horizontalOrientationConstraints.forEach { $0.isActive = false }
    verticalOrientationConstraints.forEach { $0.isActive = true }
  } else {
    verticalOrientationConstraints.forEach { $0.isActive = false }
    horizontalOrientationConstraints.forEach { $0.isActive = true }
  }
  self.updateDoneButton()
}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
  for constraint in horizontalOrientationConstraints + verticalOrientationConstraints {
    constraint.isActive = false
  }
}