如果使用Storyboard,则可以使用Interface Builder将自动布局约束添加到视图中,并且可以非常轻松地为所需的每个大小类添加不同的constant
值。当您运行应用程序并在大小类之间切换时,UI将自动更新并重新定位以尊重新大小类的正确constant
值。
我的问题是如何以编程方式获得相同的行为?
创建NSLayoutConstraint
时,无法为不同的大小类设置不同的值。因此,我认为这将是一个更加手动的过程。您必须使用viewDidLoad
中当前大小类的正确值创建约束,然后您必须使用willTransitionToTraitCollection
或updateConstraints
并检测新大小class,然后针对适用于新大小类的所有约束更改constant
,然后在需要重新定位的视图上调用layoutIfNeeded
。这将是很多代码,更糟糕的是你优化的更大的类。有没有更简单和/或更有效的方式来以编程方式获得该行为?
请注意,此问题不仅限于自动布局约束,而是任何可以使其属性值根据大小类更改的对象。例如,为不同的大小类设置UILabel
的字体。
答案 0 :(得分:1)
您需要创建不同的NSLayoutConstraint
。
根据下面的讨论进行编辑。
@Joey:您必须同时处理viewDidLoad
(或类似)和viewWillTransitionToSize
中的尺寸类决定。
尺寸等级检测应在animateAlongsideTransition
块内完成,而不是之前。
重构代码:
override func viewDidLoad() {
super.viewDidLoad()
let narrow = self.view.traitCollection.horizontalSizeClass
== UIUserInterfaceSizeClass.Compact
self.useNarrowConstraints(narrow)
}
override func viewWillTransitionToSize(size: CGSize,
withTransitionCoordinator
coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
coordinator.animateAlongsideTransition({
(UIViewControllerTransitionCoordinatorContext) -> Void in
let narrow = self.view.traitCollection.horizontalSizeClass
== UIUserInterfaceSizeClass.Compact
self.useNarrowConstraints(narrow)
})
{ (UIViewControllerTransitionCoordinatorContext) -> Void in
}
}
使用激活:
func useNarrowConstraints(narrow: Bool) {
if narrow {
NSLayoutConstraint.deactivateConstraints([self.fullWidthConstraint])
NSLayoutConstraint.activateConstraints([self.halfWidthConstraint])
} else {
NSLayoutConstraint.deactivateConstraints([self.halfWidthConstraint])
NSLayoutConstraint.activateConstraints([self.fullWidthConstraint])
}
}
进一步详情here。
使用替换
func useNarrowConstraints(narrow: Bool) {
view.removeConstraint(constraint)
if narrow {
constraint = NSLayoutConstraint.constraintsWithVisualFormat("format", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)
} else {
constraint = NSLayoutConstraint.constraintsWithVisualFormat("otherFormat", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDictionary)
}
view.addConstraint(constraint)
}