按钮不改变位置
Button not changing position
我有一个家庭作业,我们需要一个 "timer" 来计算这个点移动了多少次(它 运行 在计时器上,但它是一个整数)。我的教授给我们的源代码工作正常,但是当我将 updateTime() 调用添加到 moveButton() 调用时,它立即停止工作,只有计时器会 运行,而不是两者。
func updateTimer (){
value = value + 1;
timerLabel.text = "Time: " + String(value);
if (value >= 20){
gameOver = true;
}
}
func moveButton(t:NSTimer){
if (!gameOver && !paused){
let aWidth = self.view.bounds.size.width;
let aHeight = self.view.bounds.size.height;
let btnX = random() % (Int)(aWidth-60);
let btnY = random() % (Int)(aHeight-60);
button.frame = CGRectMake(CGFloat(btnX), CGFloat(btnY), 30.0, 30.0);
updateTimer();
}
}
override func viewDidLoad() {
super.viewDidLoad()
srandom(arc4random());
timer = NSTimer.scheduledTimerWithTimeInterval(1.5, target: self, selector: Selector("moveButton:"), userInfo: nil, repeats: true)
}
如您所见,加载视图时它会启动计时器。计时器调用 moveButton(t:NSTimer) 最终调用 updateTimer() 方法。如果您删除 updateTimer() 方法调用,它将正常工作。所以我尝试一次删除 1 行以查看导致问题的原因,问题是将 timerLabel.text 设置为时间。为什么那会阻止点移动?为什么它不能更新标签文本并移动按钮?
您可能正在使用自动布局(即您在 IB 中定义了定义按钮位置的约束)。问题是,当您更新标签的文本时,会自动重新应用自动布局约束,因此您调整按钮 frame
的尝试被阻止了。
有很多方法可以解决这个问题。
恕我直言,最好的方法是为按钮的 top
和 leading
约束创建出口。然后,您可以使用您创建的出口以编程方式调整这两个约束的 constant
属性。
绕过自动布局的方法不太优雅,包括:
设置按钮使其没有约束(例如在 IB 中编辑约束并单击 "Remove at build time" 选项;
以编程方式删除与按钮关联的约束;或
关闭自动布局。
然后你可以调整按钮的frame
而不用担心当标签更新时自动布局引擎将它移回原来的位置。
但是,我倾向于为约束添加出口,然后您可以让自动布局引擎为您移动按钮。
- 将奥特莱斯添加到布局约束
如果您在 XCode 中打开拆分视图,然后右键单击按钮上的约束,例如顶部约束,您可以按住右键并拖动到该按钮的控制器上。当你放手时,你将能够为该按钮创建一个约束插座。
从这里您可以添加或减去该约束以使用以下方法移动按钮:
constraintTop.constant = x
constraintLeft.constant = y
我有一个家庭作业,我们需要一个 "timer" 来计算这个点移动了多少次(它 运行 在计时器上,但它是一个整数)。我的教授给我们的源代码工作正常,但是当我将 updateTime() 调用添加到 moveButton() 调用时,它立即停止工作,只有计时器会 运行,而不是两者。
func updateTimer (){
value = value + 1;
timerLabel.text = "Time: " + String(value);
if (value >= 20){
gameOver = true;
}
}
func moveButton(t:NSTimer){
if (!gameOver && !paused){
let aWidth = self.view.bounds.size.width;
let aHeight = self.view.bounds.size.height;
let btnX = random() % (Int)(aWidth-60);
let btnY = random() % (Int)(aHeight-60);
button.frame = CGRectMake(CGFloat(btnX), CGFloat(btnY), 30.0, 30.0);
updateTimer();
}
}
override func viewDidLoad() {
super.viewDidLoad()
srandom(arc4random());
timer = NSTimer.scheduledTimerWithTimeInterval(1.5, target: self, selector: Selector("moveButton:"), userInfo: nil, repeats: true)
}
如您所见,加载视图时它会启动计时器。计时器调用 moveButton(t:NSTimer) 最终调用 updateTimer() 方法。如果您删除 updateTimer() 方法调用,它将正常工作。所以我尝试一次删除 1 行以查看导致问题的原因,问题是将 timerLabel.text 设置为时间。为什么那会阻止点移动?为什么它不能更新标签文本并移动按钮?
您可能正在使用自动布局(即您在 IB 中定义了定义按钮位置的约束)。问题是,当您更新标签的文本时,会自动重新应用自动布局约束,因此您调整按钮 frame
的尝试被阻止了。
有很多方法可以解决这个问题。
恕我直言,最好的方法是为按钮的
top
和leading
约束创建出口。然后,您可以使用您创建的出口以编程方式调整这两个约束的constant
属性。绕过自动布局的方法不太优雅,包括:
设置按钮使其没有约束(例如在 IB 中编辑约束并单击 "Remove at build time" 选项;
以编程方式删除与按钮关联的约束;或
关闭自动布局。
然后你可以调整按钮的
frame
而不用担心当标签更新时自动布局引擎将它移回原来的位置。
但是,我倾向于为约束添加出口,然后您可以让自动布局引擎为您移动按钮。
- 将奥特莱斯添加到布局约束
如果您在 XCode 中打开拆分视图,然后右键单击按钮上的约束,例如顶部约束,您可以按住右键并拖动到该按钮的控制器上。当你放手时,你将能够为该按钮创建一个约束插座。
从这里您可以添加或减去该约束以使用以下方法移动按钮:
constraintTop.constant = x
constraintLeft.constant = y