SwiftUI实现字符串逐字符展示及数组字符串轮询切换
实现SwiftUI字符串数组的逐字符展示+循环切换效果
要实现逐字符展示每个字符串、完成后再切换下一个的效果,我们需要新增状态变量跟踪当前字符串的已展示字符数,同时调整计时器逻辑,分逐字符展示和切换字符串两个阶段执行。以下是修改后的完整代码:
struct ContentView: View { @State private var currentIndex: Int = 0 @State private var currentCharCount: Int = 0 var fontColor: String var displayData: [String] // 双计时器分工:控制逐字符展示、控制字符串切换 private let charTimer = Timer.publish(every: 0.2, on: .main, in: .common).autoconnect() private let switchTimer = Timer.publish(every: 2.0, on: .main, in: .common).autoconnect() var body: some View { ZStack { // 展示当前字符串的前currentCharCount个字符 Text(currentDisplayText) .foregroundColor(Color(hex: fontColor)) .font(.uiFont(.subtitle3)) .animation(.easeInOut(duration: 0.2), value: currentCharCount) } .onReceive(charTimer) { _ in guard !displayData.isEmpty else { return } let currentString = displayData[currentIndex] if currentCharCount < currentString.count { currentCharCount += 1 } else { // 字符串展示完成,暂停逐字符计时器 charTimer.upstream.connect().cancel() } } .onReceive(switchTimer) { _ in guard !displayData.isEmpty else { return } // 切换到下一个字符串 currentIndex = (currentIndex + 1) % displayData.count // 重置字符计数并重启逐字符计时器 currentCharCount = 0 _ = charTimer.upstream.connect() } .onAppear { guard !displayData.isEmpty else { return } _ = charTimer.upstream.connect() } } // 计算当前要展示的文本 private var currentDisplayText: String { guard !displayData.isEmpty else { return "" } let currentString = displayData[currentIndex] return String(currentString.prefix(currentCharCount)) } } // 补充Color的hex扩展(如果你的项目中没有实现) extension Color { init(hex: String) { let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) var int: UInt64 = 0 Scanner(string: hex).scanHexInt64(&int) let a, r, g, b: UInt64 switch hex.count { case 3: // 12-bit RGB (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) case 6: // 24-bit RGB (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) case 8: // 32-bit ARGB (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) default: (a, r, g, b) = (1, 1, 1, 0) } self.init( .sRGB, red: Double(r) / 255, green: Double(g) / 255, blue: Double(b) / 255, opacity: Double(a) / 255 ) } } // 补充UI Font扩展占位(替换成你项目中的实际逻辑) extension Font { static func uiFont(_ style: some RawRepresentable) -> Font { return .system(size: 16) } }
关键逻辑说明
- 状态变量:
currentIndex控制当前展示的数组元素,currentCharCount控制当前字符串已展示的字符数。 - 双计时器分工:
charTimer:间隔0.2秒,负责逐字符增加计数,直到当前字符串全部展示完毕后暂停。switchTimer:间隔2秒(需大于当前字符串逐字符展示的总时长),负责切换到下一个数组元素,重置字符计数并重启逐字符计时器。
- 安全处理:添加了空数组判断,避免数组越界崩溃。
自定义调整方向
- 修改
charTimer的间隔(如0.15秒)可加快/减慢字符展示速度。 - 修改
switchTimer的间隔可调整每个字符串展示完成后的停留时间。 - 替换动画效果(如
.spring())可改变字符出现的动画风格。
内容的提问来源于stack exchange,提问作者Mahi Garg
相关产品推荐
相关产品推荐

