为什么这个 UILabel 的水平位置不能用自动布局动态更新?
Why can't this UILabel's horizontal position be updated dynamically with Auto Layout?
我有一个 UILabel 插座,它的顶部 space 到超级视图,前导 space 到超级视图在故事板中设置为 20。我想按一个按钮来动态更改约束以垂直和水平居中。垂直动态变化工作正常,但水平动态变化没有任何变化:
@IBAction func moveLabel(sender: AnyObject) {
self.view.addConstraint(NSLayoutConstraint(
item: self.label,
attribute: NSLayoutAttribute.CenterY,
relatedBy: NSLayoutRelation.Equal,
toItem: self.view,
attribute: NSLayoutAttribute.CenterY,
multiplier: 1,
constant: 0))
self.view.addConstraint(NSLayoutConstraint(
item: self.label,
attribute: NSLayoutAttribute.CenterX,
relatedBy: NSLayoutRelation.Equal,
toItem: self.view,
attribute: NSLayoutAttribute.CenterX,
multiplier: 1,
constant: 0))
}
水平间距保持在 20 超视图领先,但垂直间距已正确应用以居中。为什么水平居中不起作用?
如果情节提要中已经有一个顶级约束,则需要停用该约束才能应用新约束,以免发生崩溃。
您不应该在每次要移动标签时都添加约束。您应该只添加一次约束,在 viewDidLoad
甚至情节提要中,为它们创建 IBOutlets
并相应地 activate/deactivate 它们。
因此您的代码将如下所示:
@IBOutlet weak var topOffsetConstraint : NSLayoutConstraint
@IBOutlet weak var leadingOffsetConstraint : NSLayoutConstraint
@IBOutlet weak var horizontalCenterConstraint : NSLayoutConstraint
@IBOutlet weak var verticalOffsetConstraint : NSLayoutConstraint
@IBAction func moveLabel(sender: AnyObject) {
topOffsetConstranint.active = NO;
leadingOffsetConstraint.active = NO;
horizontalCenterConstraint.active = YES;
verticalOffsetConstraint.active = YES;
// If you don't need to animate the changes, remove the animation block
UIView.animateWithDuration(0.3) {
self.view.layoutIfNeeded();
}
}
我假设您想要来回移动标签。如果不是这种情况并且您的 moveLabel
方法只被调用一次,您的代码应该可以工作。只需确保停用情节提要中设置的约束并调用 layoutIfNeeded
(如果您需要,可以在动画块中调用)。
希望这对您的问题有所帮助!让我知道进展如何
我有一个 UILabel 插座,它的顶部 space 到超级视图,前导 space 到超级视图在故事板中设置为 20。我想按一个按钮来动态更改约束以垂直和水平居中。垂直动态变化工作正常,但水平动态变化没有任何变化:
@IBAction func moveLabel(sender: AnyObject) {
self.view.addConstraint(NSLayoutConstraint(
item: self.label,
attribute: NSLayoutAttribute.CenterY,
relatedBy: NSLayoutRelation.Equal,
toItem: self.view,
attribute: NSLayoutAttribute.CenterY,
multiplier: 1,
constant: 0))
self.view.addConstraint(NSLayoutConstraint(
item: self.label,
attribute: NSLayoutAttribute.CenterX,
relatedBy: NSLayoutRelation.Equal,
toItem: self.view,
attribute: NSLayoutAttribute.CenterX,
multiplier: 1,
constant: 0))
}
水平间距保持在 20 超视图领先,但垂直间距已正确应用以居中。为什么水平居中不起作用?
如果情节提要中已经有一个顶级约束,则需要停用该约束才能应用新约束,以免发生崩溃。
您不应该在每次要移动标签时都添加约束。您应该只添加一次约束,在 viewDidLoad
甚至情节提要中,为它们创建 IBOutlets
并相应地 activate/deactivate 它们。
因此您的代码将如下所示:
@IBOutlet weak var topOffsetConstraint : NSLayoutConstraint
@IBOutlet weak var leadingOffsetConstraint : NSLayoutConstraint
@IBOutlet weak var horizontalCenterConstraint : NSLayoutConstraint
@IBOutlet weak var verticalOffsetConstraint : NSLayoutConstraint
@IBAction func moveLabel(sender: AnyObject) {
topOffsetConstranint.active = NO;
leadingOffsetConstraint.active = NO;
horizontalCenterConstraint.active = YES;
verticalOffsetConstraint.active = YES;
// If you don't need to animate the changes, remove the animation block
UIView.animateWithDuration(0.3) {
self.view.layoutIfNeeded();
}
}
我假设您想要来回移动标签。如果不是这种情况并且您的 moveLabel
方法只被调用一次,您的代码应该可以工作。只需确保停用情节提要中设置的约束并调用 layoutIfNeeded
(如果您需要,可以在动画块中调用)。
希望这对您的问题有所帮助!让我知道进展如何