以编程方式为不同大小创建具有不同常量的自动布局约束 类
Programmatically create auto layout constraints with different constants for different size classes
如果您使用 Storyboard,您可以使用 Interface Builder 将自动布局约束添加到视图,并且您可以非常轻松地为您想要的每种大小添加不同的 constant
值 class。当您 运行 应用程序并在尺寸 class 之间切换时,UI 将自动更新并重新定位以尊重新尺寸 class 的正确 constant
值.
我的问题是如何以编程方式获得相同的行为?
当您创建 NSLayoutConstraint
时,您不能为不同大小的 class 设置不同的值。因此,我认为这将是一个更加手动的过程。例如,您必须为 viewDidLoad
中的当前大小 class 创建具有正确值的约束,然后您必须使用 willTransitionToTraitCollection
或 updateConstraints
并且检测新尺寸 class,然后更改适合新尺寸 class 的所有约束的 constant
,然后在需要的视图上调用 layoutIfNeeded
重新定位。那将是很多代码,更糟糕的是你优化的大小 classes。有没有一种更简单 and/or 更有效的方法来以编程方式获得该行为?
请注意,此问题不限于自动布局约束,而是任何可以根据大小更改其属性值的对象 class。例如,设置 UILabel
的字体为不同大小 classes.
Swift
您需要创建不同的集合NSLayoutConstraint
。
根据下面的讨论进行编辑。
@Joey:您必须在 viewDidLoad
(或类似)和 viewWillTransitionToSize
.[=19= 中处理大小 classes 决定]
大小 class 检测应该在 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])
}
}
更多详细信息。
使用替换:
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)
}
如果您使用 Storyboard,您可以使用 Interface Builder 将自动布局约束添加到视图,并且您可以非常轻松地为您想要的每种大小添加不同的 constant
值 class。当您 运行 应用程序并在尺寸 class 之间切换时,UI 将自动更新并重新定位以尊重新尺寸 class 的正确 constant
值.
我的问题是如何以编程方式获得相同的行为?
当您创建 NSLayoutConstraint
时,您不能为不同大小的 class 设置不同的值。因此,我认为这将是一个更加手动的过程。例如,您必须为 viewDidLoad
中的当前大小 class 创建具有正确值的约束,然后您必须使用 willTransitionToTraitCollection
或 updateConstraints
并且检测新尺寸 class,然后更改适合新尺寸 class 的所有约束的 constant
,然后在需要的视图上调用 layoutIfNeeded
重新定位。那将是很多代码,更糟糕的是你优化的大小 classes。有没有一种更简单 and/or 更有效的方法来以编程方式获得该行为?
请注意,此问题不限于自动布局约束,而是任何可以根据大小更改其属性值的对象 class。例如,设置 UILabel
的字体为不同大小 classes.
Swift
您需要创建不同的集合NSLayoutConstraint
。
根据下面的讨论进行编辑。
@Joey:您必须在
viewDidLoad
(或类似)和viewWillTransitionToSize
.[=19= 中处理大小 classes 决定]大小 class 检测应该在
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])
}
}
更多详细信息
使用替换:
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)
}