Autumn Sale50% offCOMPOT
Texts & TypographyFree ComponentiOS 16.0+Xcode 15+

Text Typing & Retracting Animation

Typewriter effect that types out and deletes sentences with a blinking cursor.

SwiftUI Implementation

Pure Vanilla Swift • No Dependencies
textTypingRetractingAnimation.swift
import SwiftUI

struct UseTextTypingRetractingAnimation: View {
    
    var body: some View {
        VStack {
            TextTypingRetractingAnimation(textsToAnimate: ["We stay hungry.", "We stay foolish.", "We promise.", "Thank you Steve!"])
        }
        .padding()
    }
}

#Preview {
    UseTextTypingRetractingAnimation()
}

struct TextTypingRetractingAnimation: View {

    var textsToAnimate: [String]
    @State private var animatedText: String = ""
    @State private var currentIndex: Int = 0
    @State private var isAnimating: Bool = false

    var body: some View {
        VStack {
            Text(animatedText)
                .font(.system(size: 22, weight: .bold, design: .serif))
                .padding()
                .frame(height: 80)
        }
        .onAppear {
            guard !textsToAnimate.isEmpty else { return }
            animateText()
        }
    }

    private func animateText() {
        guard currentIndex < textsToAnimate.count else { return }

        let text = textsToAnimate[currentIndex]
        animatedText = ""
        isAnimating = true

        // Type out the text
        for (index, character) in text.enumerated() {
            DispatchQueue.main.asyncAfter(deadline: .now() + Double(index) * 0.12) {
                animatedText.append(character)

                // Check if it's the last character
                if index == text.count - 1 {
                    // If it's not the last text, initiate the retraction animation
                    if currentIndex < textsToAnimate.count - 1 {
                        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                            retractText()
                        }
                    } else {
                        // If it's the last text, stop the animation
                        isAnimating = false
                    }
                }
            }
        }
    }

    private func retractText() {
        let text = animatedText
        for index in 0..<text.count {
            DispatchQueue.main.asyncAfter(deadline: .now() + Double(index) * 0.1) {
                guard !animatedText.isEmpty else { return }
                animatedText.removeLast()

                // Check if it's the last character
                if animatedText.isEmpty {
                    // Move to the next text
                    currentIndex += 1
                    isAnimating = false
                    if currentIndex < textsToAnimate.count {
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                            animateText()
                        }
                    }
                }
            }
        }
    }

    private func restartAnimation() {
        currentIndex = 0
        animatedText = ""
        guard !textsToAnimate.isEmpty else { return }
        animateText()
    }
}

Ready to copy and paste directly into any Xcode project running iOS 16.0+.

Recommended Use Cases

  • First-run onboarding flows and feature introductions
  • Paywalls, upgrade prompts, and subscription tiers

Component Details

iOS Compatibility
iOS 16.0+
Xcode Version
Xcode 15+
Platform
iOS
License Tier
Free
Themes & Contexts
onboardingpaywall
Keywords
textanimationtypingretractingsteve jobs
C

Compot for iOS

Native SwiftUI playground app

Preview all 130+ components interactively on your device and copy code straight to Xcode with 1 tap.

Get Compot on the App Store