Skip to content

Instantly share code, notes, and snippets.

@kaunteya
Last active July 23, 2024 15:58
Show Gist options
  • Select an option

  • Save kaunteya/828aa10dd970c8b1396e2a3b37b56a6e to your computer and use it in GitHub Desktop.

Select an option

Save kaunteya/828aa10dd970c8b1396e2a3b37b56a6e to your computer and use it in GitHub Desktop.
SwiftUI view that displays content gradually
//
// AnimatedText.swift
//
// Created by Kauntey Suryawanshi on 23/07/24.
//
import SwiftUI
struct AnimatedText: View {
enum Speed {
case fast, normal, slow
var duration: Duration {
switch self {
case .fast: .milliseconds(50)
case .normal: .milliseconds(100)
case .slow: .milliseconds(200)
}
}
/// Newline takes a longer wait
var durationNewLine: Duration {
switch self {
case .fast: .milliseconds(500)
case .normal: .milliseconds(1000)
case .slow: .milliseconds(2000)
}
}
}
let text: AttributedString
let speed: Speed
let wait: Duration
@State private var endIndex: AttributedString.Index
init(_ text: AttributedString, speed: Speed = .normal, wait: Duration = .zero) {
self.text = text
self.wait = wait
self.speed = speed
endIndex = self.text.startIndex
}
init(_ text: String, speed: Speed = .normal, wait: Duration = .zero) {
self.init(AttributedString(text), speed: speed, wait: wait)
}
var body: some View {
Group {
Text(AttributedString(text[text.startIndex ..< endIndex]))
+ Text(AttributedString(text[endIndex ..< text.endIndex]))
.foregroundColor(.clear)
}
.animation(.default, value: endIndex)
.task {
try? await Task.sleep(for: wait)
for i in text.characters.indices {
if text.characters[i].isNewline {
endIndex = i
try? await Task.sleep(for: speed.durationNewLine)
} else if text.characters[i].isWhitespace || text.characters.endIndex == i {
endIndex = i
try? await Task.sleep(for: speed.duration)
}
}
endIndex = text.endIndex
}
}
}
#Preview {
var attrString = AttributedString("Mark my words\n")
attrString.font = Font(NSFont.systemFont(ofSize: 21))
attrString.append(AttributedString("Long term capital gains for all asset classes is going to be 12.5%. You may worry about your stocks and equity funds. Actually that is very less of your concern.\nYou pay 2.5% more than earlier now."))
return VStack(alignment: .leading, spacing: 10) {
AnimatedText(attrString, speed: .normal)
}
.padding()
.frame(width: 500, height: 500)
}
@kaunteya
Copy link
Copy Markdown
Author

Demo

Untitled.mov

This SwiftUI view displays text gradually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment