SwiftUI 键盘弹出一次输入并不断出现和消失
Posted
技术标签:
【中文标题】SwiftUI 键盘弹出一次输入并不断出现和消失【英文标题】:SwiftUI Keyboard pops up once for Input and keeps appearing and disappearing 【发布时间】:2020-12-19 21:42:32 【问题描述】:我是 Swift 编程的新手,我正在尝试通过一些 YouTube 教程学习如何构建自己的聊天应用程序。我已经走了很远,但遇到了障碍。我不明白为什么当我尝试输入 TextField 时,它第一次可以正常工作,但如果我随后再点击那里,键盘会弹出然后立即消失。
.clipShape(Rectangle())
的代码行原本是.clipShape(RoundedShape())
,但那会切断消息,所以我默认为Rectangle()
。我认为这与我的 TextField 或 Rectangle()
有关。用键盘看看下面的截图(第一次尝试):
下面是我的代码:
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:
ScrollViewReaderreader 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, .bottomLeft, .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 代码本身存在什么问题。我所有的其他文本字段都很好。任何帮助,将不胜感激!谢谢。
【问题讨论】:
【参考方案1】:我不确定发生这种情况的确切原因,但您可以只塑造背景层而不是实际的 TextField,您将获得相同的 UI 结果。
.background(
Color.black
.opacity(0.06)
.clipShape(Capsule())
)
//.clipShape(Capsule())
【讨论】:
我不知道为什么会这样,但确实有效!谢谢!我赞成你的回答。您介意解释一下为什么会这样吗? 我也不是 100% 确定原因。这对我来说似乎是一个错误......我认为它与垂直填充和 .clipShape 在同一层上有关......因为如果我删除了垂直填充,问题也会消失。因此,解决方案是将 .clipShape 移动到与垂直填充渲染所在不同的层上。现在,我们不再将 HStack 变成 Capsule,而是将 Color.black 变成 Capsule。 (我希望我能给你一个更好的答案,哈哈)。以上是关于SwiftUI 键盘弹出一次输入并不断出现和消失的主要内容,如果未能解决你的问题,请参考以下文章