I'm new to Swift and I'm trying to implement a simple game. In this game, once the view is loaded I want periodic animations to happen.
The problem is that I try to animate my buttons with, for instance, button.frame.origin.x += 50
, but instead of moving it from the origin to 50px right, it appears at button.frame.origin.x - 50 and goes to its (initial) position.
Funnily enough, at one point I show an AlertDialog
to the user, and after it is shown the animation starts to happen as I expected.
My problem is the same of this topic, but the accepted answer just didn't solve it for me.
Any thoughts?
Edit: Digging into the code and testing a lot I found out the method where I show the AlertDialog also happens to invalidate my timer. I have two timers: one to update the UI time (a TextField), and the other to perform the animation. Both are scheduling a task. From what I read here, it is not possible to have two timers like that.
A timer object can be registered in only one run loop at a time, although it can be added to multiple run loop modes within that run loop.
Hence, the obvious solution would be to merge the two selectors (functions) into one, so the timer would work for both tasks. However, if I try to update the UI AND perform animations, the animations don't work as expected anymore. I'm just lost on this problem and can't make both things work.
These are my important pieces of code:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
...
resetOrCreateGame()
}
func resetOrCreateGame() {
// Do stuff to initialize values
timerToRotate = NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: "rotateBlocks", userInfo: nil, repeats: true)
}
func rotateBlocks() {
// Calculate positions to rotate
UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
// Try to update a timer in the UI
//self.timeLeft.text = String(self.seconds)
for i in 0 ... 8 {
println("\(i) before \(self.buttons[i].frame.origin.x) \(self.buttons[i].frame.origin.y)")
self.buttons[i].frame.origin.x = self.positions[self.indicesToRotate[i]].x
self.buttons[i].frame.origin.y = self.positions[self.indicesToRotate[i]].y
println("\(i) after \(self.buttons[i].frame.origin.x) \(self.buttons[i].frame.origin.y)")
}
}, completion: { _ in
println("completed")
})
If I leave the line self.timeLeft.text = String(self.seconds)
commented, the animations work fine. No matter how I try to update the timeLeft, if I do so it screws my animations. I tried to update it in a separate thread, dispatch it to the main thread, or even update it inside the animations closure: it just doesn't work.