SwiftUI 键盘为 Input 弹出一次并不断出现和消失

问题描述

我是 Swift 编程的新手,正在尝试通过一些 YouTube 教程学习如何构建自己的聊天应用程序。我已经走了很远,但遇到了障碍。我不明白为什么当我尝试输入 TextField 时,它第一次工作正常,但如果我在随后的任何时间点击那里,键盘会弹出然后立即消失。

.clipShape(Rectangle())代码行最初是 .clipShape(RoundedShape()),但这会切断消息,所以我认为 Rectangle()。我认为这与我的 TextField 或 Rectangle() 有关。用键盘查看下面的截图(第一次尝试):

iOS simulator with keyboard

这是我的代码如下:

import SwiftUI

struct ChatUIView: View {
    
    @State var message = ""
    //StateObject is the owner of the object...
    @StateObject var allMessages = Messages()
    
    var body: some View {
        vstack{
            
            ZStack{
                
                /*
                HStack{
                    Spacer()
                }*/
                
                vstack(spacing:5){
                    Text("Chat")
                        .fontWeight(.bold)
                }
                .foregroundColor(.white)
            }
            .padding(.all)
            
            //Spacer()
            vstack{
                
                //Spacer()
                //displaying Message...
                
                ScrollView(.vertical,showsIndicators: false,content: {
                    
                    ScrollViewReader{reader in
                        
                        vstack(spacing: 20){
                            
                            ForEach(allMessages.messages){msg in
                                
                                //Chat Bubbles...
                                
                                ChatBubble(msg: msg)
                            
                                
                            }
                            //whenever new data is inserted,scroll to bottom...
                            .onChange(of: allMessages.messages) {(value) in
                                
                                //scrolling only user message...
                                
                                if value.last!.myMsg{
                                    reader.scrollTo(value.last?.id)
                                }
                                
                            }
                        }
                        .padding([.horizontal,.bottom])
                        .padding(.top,25)
                    }
                })
                
                HStack(spacing:15){
                    
                    HStack(spacing: 15){
                        TextField("Message",text: self.$message)
                    }
                    .padding(.vertical,12)
                    .padding(.horizontal)
                    .background(Color.black.opacity(0.06))
                    .clipShape(Capsule())
                    
                    
                    //send button
                    //hiding view...
                    if message != ""{
                        Button(action: {
                            
                            //appending message...
                            
                            //adding animation...
                            withAnimation(.easeIn){
                                allMessages.messages.append(Message(id: Date(),message: message,myMsg: true))
                            }
                            message = ""
                            
                        },label: {
                            
                            Image("send")
                                .resizable()
                                .frame(width: 25,height: 25)
                                .rotationEffect(.init(degrees: 45))
                                .padding()
                                //.aspectRatio(contentMode: .fit)
                                //.font(.system(size: 0.5))
                                //.padding(.all)
                                .background(Color.black.opacity(0.07))
                                .clipShape(Circle())
                        })
                    }
                }
                .padding(.horizontal)
                .animation(.eaSEOut)
            }
            .padding(.bottom,UIApplication.shared.windows.first?.safeAreaInsets.bottom)
            .background(Color.white)
            //.clipShape(RoundedShape())
            .clipShape(Rectangle())
            .keyboardType(.default)
        }
        //.edgesIgnoringSafeArea(.bottom)
        .background(Color.blue.edgesIgnoringSafeArea(.top))
    }
}

//Chat Bubbles...

struct ChatBubble : View {
    
    var msg : Message
    var body: some View{
        
        //Automatics scroll to bottom...
        //First assigning id to each row
        
        HStack(alignment: .top,spacing: 10){
            
            if msg.myMsg{
                
                //pushing msg to the left...
                
                //minimum space ...
                Spacer(minLength: 25)
                
                Text(msg.message)
                    .padding(.all)
                    .background(Color.black.opacity(0.06))
                    //.cornerRadius(15)
                    .clipShape(BubbleArrow(myMsg: msg.myMsg))
            } else {
                
                //pushing msg to the right...
                
                Text(msg.message)
                    .fixedSize(horizontal: false,vertical: true)
                    .lineLimit(nil)
                    .foregroundColor(.white)
                    .padding(.all)
                    //.background(Color.black.opacity(0.06))
                    .background(Color.blue)
                    .clipShape(BubbleArrow(myMsg: msg.myMsg))
                
                Spacer(minLength: 25)
            }
        }
        .id(msg.id)
        //.padding(msg.myMsg ? .leading : .trailing,55)
        //.padding(.vertical,10)
    }
}

// Bubble Arrow...

struct BubbleArrow : Shape {
    
    var myMsg : Bool
    
    
    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(roundedRect: rect,byRoundingCorners: myMsg ? [.topLeft,.bottomLeft,.bottomright] : [.topRight,.bottomright],cornerRadii: CGSize(width: 10,height: 10))
        
        return Path(path.cgPath)
    }
}


// Custom Rounded Shape...

struct RoundedShape : Shape {
    
    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(roundedRect: rect,byRoundingCorners: [.topLeft,.topRight],cornerRadii: CGSize())
        
        return Path(path.cgPath)
    }
}

// Model Data For Message...

struct Message : Identifiable,Equatable {
    
    var id: Date
    var message: String
    var myMsg: Bool
    //var profilePic: String
    //var photo: Data?
    
}

class Messages: ObservableObject {
    
    @Published var messages : [Message] = []
    
    //sample data...
    init() {
        let strings = ["Hi!","hello!","How are you doing?!","Fine,I just want to talk about life","ok,I may be able to help with that","This is awesome,thanks","So what do you want to talk about?","movies sound like a good topic. Let's start there!","Ok,so tell me: What's you favorite movie? LKASJLDJGLSJGOJOSGJDOJGOSDJNOGNSDOGNISNO","Definitely,interstellar for sure."]
        
        for i in 0..<strings.count{
            
            //simple logic for two sided message View...
            
            messages.append(Message(id: Date(),message: strings[i],myMsg: i % 2 == 0 ? false : true))
        }
    }
    
    func writeMessage(id: Date,msg: String,photo: Data?,myMsg: Bool){
        
        messages.append((Message(id: id,message: msg,myMsg: myMsg)))
        
        
    }
}

同样,我不确定我的 SwiftUI 代码本身存在什么问题。我所有的其他 TextField 都很好。任何帮助,将不胜感激!谢谢。

解决方法

我不确定发生这种情况的确切原因,但您可以只调整背景层而不是实际的 TextField,您将获得相同的 UI 结果。

.background(
    Color.black
        .opacity(0.06)
        .clipShape(Capsule())
)
//.clipShape(Capsule())