I have a homework assignment where we need to have a "timer" that counts how many times this dot moves (it runs on a timer but is an int). The source code my professor gave us works fine but when I add an updateTime() call to the moveButton() call it immediately stops working and only the timer will run instead, not both.
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)
}
As you can see as the view loads it starts the timer. The timer calls moveButton(t:NSTimer) which eventually calls the updateTimer() method. If you remove the updateTimer() method call it will work fine. So I tried removing 1 line at a time to see what was causing the problem and the problem is setting timerLabel.text to the time. Why would that stop the dot from moving? Why can't it update the label text AND move the button?
Likely you are using auto-layout (i.e. you have constraints defined in IB that define the location of the button). The problem is that when you update the text of the label, auto-layout constraints are automatically reapplied, and thus your attempt to adjust the button frame
is being thwarted.
There are a bunch of ways of solving this.
The best way, IMHO, is to create outlets for the top
and leading
constraints of the button. Then you can programmatically adjust the constant
properties for those two constraints using the outlets you have created.
There are less elegant approaches that bypass auto-layout, including:
set up the button so it has no constraints (e.g. edit the constraints in IB and click on the "Remove at build time" option;
programmatically removing the constraints associated with the button; or
turning off auto-layout.
Then you can adjust the frame
of the button without fear of the auto-layout engine moving it back to the original position when the label is updated.
But, I'd lean towards adding outlets for the constraints, and then you can have the autolayout engine move the button for you.