我有一个UILabel插座,其顶层空间可以超视图,并且在故事板中将superview设置为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))
}
从superview开始,水平间距保持在20,但垂直间距正确应用于居中。为什么水平中心不起作用?
答案 0 :(得分:1)
如果故事板中已经有一个顶级约束,则需要停用该条件以应用新约束,而不是发生崩溃。
每次要移动标签时都不应添加约束。您应该只在viewDidLoad
甚至故事板中添加约束一次,为它们创建IBOutlets
并相应地激活/停用它们。
所以你的代码看起来像这样:
@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
(可能在动画块中,如果这是你需要的那样)。
希望这有助于解决您的问题!让我知道它是怎么回事