Search code examples
iosswifttimeruitextview

UITextView Typing Animation


I have a uitextview with a fixed width and height.

To make the text more digestible, I wanted to perform a character-by-character typing "animation", and was able to get it to work using a Timer object.

My only issue is...when the 1st character is typed for a word that will spill over to the next line, instead of typing that 1st character on the next line, it types on the current line. When the typing hits the end of the uitextview, it's only then that all the previously typed characters of the word are brought over to the next line.

This results in a jerky typing animation, and I'm wondering if it's at all possible to make it smoother by typing the first character on a new line ahead of time. Any guidance would be greatly appreciated!

Here is my current function:

func type(text: String) {

    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = .center
    paragraphStyle.lineBreakMode = .byWordWrapping
    paragraphStyle.paragraphSpacing = 10

    let bodyAttributes = [
        NSAttributedString.Key.foregroundColor: UIColor.black,
        NSAttributedString.Key.paragraphStyle: paragraphStyle,
        NSAttributedString.Key.font: UIFont.systemFont(ofSize: 17)
    ]

    let characters = Array(text)
    var characterIndex = 0

    let attributedString = NSMutableAttributedString()

    Timer.scheduledTimer(withTimeInterval: 0.05, repeats: true) { [weak self] timer in
        guard let self = self else { return }

        while characters[characterIndex] == " " {
            attributedString.append(NSAttributedString(string: " ", attributes: bodyAttributes))
            textView.attributedText = attributedString

            characterIndex += 1

            if characterIndex == characters.count {
                timer.invalidate()
                return
            }
        }

        let char = String(characters[characterIndex])
       
            attributedString.append(NSAttributedString(string: char, attributes: bodyAttributes))
        
        textView.attributedText = attributedString

        characterIndex += 1

        if characterIndex == characters.count {
            timer.invalidate()
        }
    }
}

Re: Naveet's answer, result: enter image description here


Solution

  • discovered a repo that creates a custom uitextview