Omer Harel
Omer Harel

Reputation: 283

How to set timer for random colour in swift 2?

i want to set timer and change the background color every 5 seconds.

I wrote code of random color and its work perfect , but i tried to put the function in NSTimer and i getting crush.

2016-03-05 14:46:48.774 Boo Adventure[6782:365555] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Boo_Adventure.GameScene update]: unrecognized selector sent to instance 0x7fe2cb741ac0'

Game Scene :

extension CGFloat {
    static func random() -> CGFloat {
        return CGFloat(arc4random()) / CGFloat(UInt32.max)
    }
}


extension UIColor {
    static func randomColor() -> UIColor {
        let r = CGFloat.random()
        let g = CGFloat.random()
        let b = CGFloat.random()

        // If you wanted a random alpha, just create another
        // random number for that too.
        return UIColor(red: r, green: g, blue: b, alpha: 2.5)
    }
}

override func didMoveToView(view: SKView) {

        Timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "update", userInfo: nil, repeats: false)

        func update() {

            self.view!.backgroundColor = UIColor.randomColor()

        }
}

Thanks!

Upvotes: 1

Views: 687

Answers (3)

Whirlwind
Whirlwind

Reputation: 13665

Few issues here:

1) You want to change color every 5 seconds, but you set repeats parameter to false, so your custom update() method will be executed only once. Change repeats to true.

2) You are trying to change the background color of a view (SKView) instead of a background color of the scene.

Here is how you can do it with NSTimer:

override func didMoveToView(view: SKView) {
      let timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update", userInfo: nil, repeats: true)
}

func update(){
      backgroundColor = UIColor.randomColor()
}

But NSTimer is not affected by the scene's or view's paused state, so it can take you into troubles in certain situations. To avoid this, you can use SKAction. The same thing done with SKAction looks like this:

override func didMoveToView(view: SKView) {

        let wait = SKAction.waitForDuration(5)

        let block = SKAction.runBlock({
            [unowned self] in
            self.backgroundColor = UIColor.randomColor()
        })

        let sequence = SKAction.sequence([wait,block])

        runAction(SKAction.repeatActionForever(sequence), withKey: "colorizing")

    }

This way, if you pause your scene or a view, colorizing action will be paused automatically (and unpaused when scene/view are unpaused).

Upvotes: 2

João Costa
João Costa

Reputation: 21

Don't know if this fixes the problem but according to the NSTimer Class Reference the selector should have the signature:

timerFireMethod:

Try updating your update function signature to

func update(timer: NSTimer)

And update this line:

Timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "update", userInfo: nil, repeats: false)

to:

Timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "update:", userInfo: nil, repeats: false)

Upvotes: 0

Russell
Russell

Reputation: 5554

your function update looks like it's in a closure for the timer - but it's not. take the function out so that it looks like this

override func didMoveToView(view: SKView) {
   Timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "update", userInfo: nil, repeats: false)
}

func update() {
    self.view!.backgroundColor = UIColor.randomColor()
}

Upvotes: 0

Related Questions