3

I want to to animate appearance of Label's text so that it looks like it is being typed in at the moment. I was wondering if there is a relatively easy way to do so in SWIFT. Thank you.

Michael Voline
  • 383
  • 3
  • 13

2 Answers2

3

Try this:

class GameScene : SKScene {

    let text = ["G", "a", "m", "e"]

    var labelText = ""

    let labelNode = SKLabelNode()

    var calls : Int = 0

    var timer : NSTimer!

    override func didMoveToView(view: SKView) {

        timer = NSTimer.scheduledTimerWithTimeInterval(YOUR_DESIRED_INTERVAL, target: self, selector: #selector(self.updateLabelText), userInfo: nil, repeats: true)

        labelNode.text = labelText
        self.addChild(labelNode)
    }


    func updateLabelText() {

        labelText += text[calls]
        labelNode.text = labelText
        calls += 1

        if calls == text.count + 1 {
            timer.invalidate()
    }
}
Wes
  • 1,032
  • 7
  • 11
  • Using timers in Spritekit is not a good idea because these timing methods ignore a node's, scene's or the view's paused state. The second answer by @Burro is much better in case somebody stumbles upon this a few years later like I did :D – Mike Apr 20 '20 at 15:05
3

I would suggest you use SKAction.wait(forDuration:) instead of timer

extension SKLabelNode{
    func startTyping(_ duration:TimeInterval, completion:(()->Void)?){
        guard let text = self.text else{return}

        self.text = ""
        var index = 0
        var block:(() -> Void)!
        block = {
            index += 1
            if index > text.count{
                completion?()
                return
            }else{
                let action = SKAction.sequence([SKAction.wait(forDuration: duration), SKAction.run{self.text = String(text.prefix(index))}])
                self.run(action, completion: block)
            }
        }
        block()
    }
}

If you want to get a type writer look, set the horizontal alignment in advance

label.horizontalAlignmentMode = .left
Burro
  • 63
  • 5