如何创建聊天GPT打印动画swiftUI

问题描述 投票:0回答:1

我使用 swiftUI 创建了一个小的 chatGPT 克隆来与他的 API 通信 我想问一下当来自 API 的响应

时如何创建打印样式的动画
struct ContentView: View {
    @ObservedObject var viewModel = ViewModel()
    @State var text = ""
    @State var models = [String]()

    var body: some View {
       
            VStack(alignment: .leading) {
                ForEach($models, id: \.self) { $string in
                    Text(string)
                }
                Spacer()
                HStack {
                    TextField("type here ...", text: $text)
                    Button("Send") {
                        send()
                    }
                }
            }
            .onAppear {
                viewModel.setup()
            }
            .padding()
    }

    private func send() {
        guard !text.trimmingCharacters(in: .whitespaces).isEmpty else { return }
        models.append("Me: \(text)")
        viewModel.send(text: text) { response in
            DispatchQueue.main.async {
                self.models.append("ChatGPT: " + response)
                self.text = ""
            }
        }
    }
}
swiftui text core-animation combine
1个回答
0
投票

你可以按单词或字母拆分文本,然后一个一个地添加,这里是一个例子。

struct ContentView: View {
    
    @State private var letters: [String] = []
    @State private var text: String = "I have created a small chatGPT clone using swiftUI to communicate with his API I want to ask how I can create print-style animation when the response some from API"
    @State private var displayText: String = ""
    @State private var animating: Bool = false
    
    var body: some View {
        VStack {
            Text(displayText)
                .frame(height: 100)
                .frame(maxWidth: .infinity, alignment: .leading)
            Button(action: animate) {
                Text("Animate")
                    .frame(maxWidth: .infinity)
                    .font(.headline)
                    .foregroundColor(.white)
                    .padding()
                    .background(animating ? .black.opacity(0.75) : .black)
                    .cornerRadius(12)
            }
            .disabled(animating)
        }
        .padding()
    }
    
    private func animate() {
        animating = true
        displayText = ""
        letters = []
        letters = Array(text).map { String($0) }
        loop()
    }
    
    private func loop() {
        let pace = 0.05
        
        if !letters.isEmpty {
            DispatchQueue.main.asyncAfter(deadline: .now() + pace) {
                displayText += letters.removeFirst()
                loop()
            }
        } else {
            animating = false
        }
        
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.