DEV Community

not-bad-dev.eth
not-bad-dev.eth

Posted on

Typewriter text effect in SwiftUI

This article walks through implementing a typewriter-style text animation in SwiftUI using pure Swift and native SwiftUI APIs, no external dependencies.

Minimum supported platforms: iOS 15.0+.

You can jump directly to the code. A complete example repository is provided at the end.
Single block of text animated using Typewriter effect text animation

About

This article walks through implementing a typewriter-style effect animation in SwiftUI using pure Swift and native SwiftUI APIs — no external dependencies.
Minimum supported iOS version is 15 and till the latest one iOS 26.

Many existing implementations rely on UIKit wrappers or just string modifications that affect text appearance and doesn’t provide desired animation that fit’s and doesn’t break layout around.

This implementation supports:

  • Custom fonts
  • Any font size
  • Any font color
  • Stable layout — the final text size is known in advance, so surrounding views remain unaffected

The key point of the animation effect is to keep a text on same positions aligned to any side and avoid text jumps during animation progress.

Implementation description

Main component of the view is an a AttributedString that used with SwiftUI native Text component that allow full text customizations modifier.

Animations starts with onAppear event on TypwriterText view. It starts with empty view without the text but the view already fill all space required for final text. The view iterates text by charactes and change .clear text color to initial text color provided for the text component. Until the full text is presented. The component provides letters appearance interval modification.

Code

How to use TypewriterText component

TypewriterText("Hello, world! Let's type it out!")
    .font(.system(.title2))
    .foregroundStyle(Color.brown)

TypewriterText("Hello, world! Let's type it out!")
    .font(.custom("Custom-Font", size: 24))
    .foregroundStyle(Color.brown)
Enter fullscreen mode Exit fullscreen mode

Multiple blocks of text animated using Typewriter effect text animation with different colours and different fonts

You can provide any custom or system font and any color that will be animated during typweriter animation.

The TypewriterText looks like this

struct TypewriterText: View {
    let text: String
    let interval: TimeInterval

    @State private var attributedText: AttributedString = ""

    init(_ text: String, interval: TimeInterval = 0.06) {
        self.text = text
        self.interval = interval
    }

    var body: some View {
        Text(attributedText)
            .onAppear {
                startAnimation()
            }
    }

    @MainActor
    private func startAnimation() {
        Task { @MainActor in
            var base = AttributedString(text)
            let initialColor = base.foregroundColor
            base.foregroundColor = .clear
            attributedText = base

            var index = base.startIndex
            while index < base.endIndex {
                let nextIndex = base.index(afterCharacter: index)
                attributedText[index..<nextIndex].foregroundColor = initialColor
                index = nextIndex
                try? await Task.sleep(nanoseconds: UInt64(interval * 1_000_000_000))
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

It uses AttributedText as main component for dynamic text appearence by changing it’s letters colors one by one.

The usage of native comonents provides good level of performance and open to customizations and modifications.

For example, you can add haptics on each letter appear by modifying startAnimation() adding haptic trigger in while cycle.

You can check example Xcode project by the link.

https://github.com/maltsevoff/TypewriterText

Top comments (0)