ScrollViewReader在Swift中显示键盘时不会向上移动

6ss1mwsb  于 2023-04-10  发布在  Swift
关注(0)|答案(1)|浏览(161)

当用户点击问题框开始输入时,键盘会出现动画,HStack(包含TextFieldButton)会相应地向上移动并显示动画。但是,活动键盘和移动的HStack会覆盖MessageView。如何更改代码,使MessageView也相应地向上移动?
下面是键盘处于非活动状态时的UI:

下面是键盘激活时的UI。键盘涵盖了最新的消息:

import SwiftUI

struct ContentView: View {
    @State var messages: [Message] = [
        Message(text: "Hello!", isMe: false),
        Message(text: "Hi there!", isMe: true),
        Message(text: "How are you?", isMe: false),
        Message(text: "I'm good, thanks. How about you?", isMe: true),
        Message(text: "I'm doing well too, thanks for asking.", isMe: false)
    ]
    @State var newMessage: String = ""
    @State var isTyping: Bool = false  // State variable to control the visibility of text field

    var body: some View {
        VStack {
            ScrollViewReader { scrollView in //
                ScrollView {
                    VStack(alignment: .leading, spacing: 10) {
                        ForEach(messages) { message in
                            MessageView(message: message)
                                .id(message.id) // Assign unique id to each message view
                        }
                    }
                    .onChange(of: messages) { _ in
                        withAnimation {
                            scrollView.scrollTo(messages.last?.id) // Scroll to last message
                        }
                    }
                }
                .onAppear {
                    scrollView.scrollTo(messages.last?.id) // Scroll to last message on appear
                }
                .gesture(
                    TapGesture()
                        .onEnded { _ in
                            // Dismiss keyboard
                            UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
                        }
                )
            }
            HStack {
                TextField("Type a message...", text: $newMessage)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                Button(action: sendMessage) {
                    Text("Send")
                }
            }
            .padding()
        }
    }

    func sendMessage() {
        messages.append(Message(text: newMessage, isMe: true))
        newMessage = ""
        // Hide text field
        isTyping = false
    }
}

struct Message: Identifiable, Equatable {
    let id = UUID()
    let text: String
    let isMe: Bool
}

struct MessageView: View {
    let message: Message

    var body: some View {
        HStack {
            if message.isMe {
                Spacer()
            }
            Text(message.text)
                .padding(10)
                .background(message.isMe ? Color.blue : Color.gray)
                .foregroundColor(.white)
                .cornerRadius(10)
            if !message.isMe {
                Spacer()
            }
        }
        .padding(message.isMe ? .leading : .trailing, 50)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
tkclm6bt

tkclm6bt1#

您可以尝试将Spacer()添加到根VStack

相关问题