Reputation: 951
I have an animation that is running fine until I change the button text from start to stop. The text changes but the animation itself disappears. What am I doing wrong?
import UIKit class ViewController: UIViewController { var counter = 1 var timer = NSTimer() var isAnimating = false @IBOutlet weak var button: UIButton! @IBOutlet weak var frogsImage: UIImageView! @IBAction func updateImage(sender: AnyObject) { if isAnimating == false { timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("doAnimation"), userInfo: nil, repeats: true) isAnimating = true button.setTitle("Stop Jumping", forState: UIControlState.Normal) } else { timer.invalidate() isAnimating = false button.setTitle("Start Jumping", forState: UIControlState.Normal) } } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } func doAnimation() { if counter == 4 { counter = 1 } else { counter++ } frogsImage.image = UIImage(named: "frame\(counter).png" ) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } override func viewDidLayoutSubviews() { // Hiding off the screen frogsImage.center = CGPointMake(frogsImage.center.x - 400, frogsImage.center.y) } override func viewDidAppear(animated: Bool) { UIView.animateWithDuration(1) { () -> Void in self.frogsImage.center = CGPointMake(self.frogsImage.center.x + 400, self.frogsImage.center.y) } } }
Upvotes: 1
Views: 1418
Reputation: 1
What's happening is that your image is going back 400 pixels to the left again. You can check this for yourself by changing the leftward shift to 40px instead and running the app. This is due to the fact that viewDidLayoutSubviews
is called in several instances and resets the location of the image to whatever you specified originally.
In other words, the method is called when
How I suggest bypassing this is to add a count variable like so
import UIKit
class ViewController : UIViewController {
var viewCount = 0 //ADD THIS
var counter = 1
var timer = NSTimer()
var isAnimating = false
@IBOutlet weak var button: UIButton!
@IBOutlet weak var frogsImage: UIImageView!
@IBAction func updateImage(sender: AnyObject) {
if isAnimating == false {
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("doAnimation"), userInfo: nil, repeats: true)
isAnimating = true
button.setTitle("Stop Jumping", forState: UIControlState.Normal)
} else {
timer.invalidate()
isAnimating = false
button.setTitle("Start Jumping", forState: UIControlState.Normal)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func doAnimation() {
if counter == 4 {
counter = 1
} else {
counter++
}
frogsImage.image = UIImage(named: "frame\(counter).png")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidLayoutSubviews() {
// ADD THIS IF BLOCK
if viewCount < 2 {
frogsImage.center = CGPointMake(frogsImage.center.x - 400, frogsImage.center.y)
viewCount++
}
}
override func viewDidAppear(animated: Bool) {
UIView.animateWithDuration(1) { () -> Void in
self.frogsImage.center = CGPointMake(self.frogsImage.center.x + 400, self.frogsImage.center.y)
}
}
}
Upvotes: 0
Reputation: 953
Here are a few things I would do differently, but I don't have it running in a project so I can't guarantee it will all work.
class ViewController: UIViewController {
var counter = 1
var timer = NSTimer()
var isAnimating = false
var didSetup = false
var didAnimateIn = false
@IBOutlet weak var button: UIButton!
@IBOutlet weak var frogsImage: UIImageView!
@IBAction func updateImage(sender: AnyObject) {
if isAnimating == false {
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("doAnimation"), userInfo: nil, repeats: true)
isAnimating = true
button.setTitle("Stop Jumping", forState: UIControlState.Normal)
} else {
timer.invalidate()
isAnimating = false
button.setTitle("Start Jumping", forState: UIControlState.Normal)
}
}
func doAnimation() {
if counter == 4 {
counter = 1
} else {
counter++
}
frogsImage.image = UIImage(named: "frame\(counter).png"
)
}
override func viewDidLayoutSubviews() {
// Change this to always call super first
super.viewDidLayoutSubviews()
// Only do this once
if !didSetup {
didSetup = true
frogsImage.center = CGPointMake(frogsImage.center.x - 400, frogsImage.center.y)
}
}
override func viewDidAppear(animated: Bool) {
// Change this to always call super
super.viewDidAppear(animated)
// Only do this once, after setup
if didSetup && !didAnimateIn {
didAnimateIn = true
UIView.animateWithDuration(1) { () -> Void in
self.frogsImage.center = CGPointMake(self.frogsImage.center.x + 400, self.frogsImage.center.y)
}
}
}
}
Upvotes: 0
Reputation: 647
The animation is stopped because you're invalidating the timer.
After invalidating the timer, you should restart it again. So, you'll have the animation running again.
Hope this helps.
Upvotes: 0