This simple TextField
might be part of a chat feature, and I would like to be able to send chat messages when I press the keyboard button "send".
(Imagine in this chat I don't need to allow users to enter newline, by overriding the return key, to be send with the submitLabel(.send)
view modifier.)
TextField(
"Chat...",
text: $draft
)
.submitLabel(.send)
.onSubmit {
if !draft.isEmpty {
sendMessage(draft: draft)
}
}
However, this will hide the keyboard, and I would like to know:
is there any way to prevent the keyboard from hiding when I press send
??
I know how to refocus the field, I can do that with @FocusState
but that still results in a hide keyboard animation starting which then aborts, so looks glithy.
CodePudding user response:
Here is something you can work with. During .onSubmit
set the focusedField
back to .field
, and use .transaction
to capture the current transaction and set the animation to nil
:
struct ContentView: View {
enum FocusField: Hashable {
case field
}
@State private var draft = "Hello, world"
@FocusState private var focusedField: FocusField?
var body: some View {
TextField(
"Chat...",
text: $draft
)
.submitLabel(.send)
.focused($focusedField, equals: .field)
.onSubmit {
focusedField = .field
if !draft.isEmpty {
sendMessage(draft: draft)
}
}
.transaction { t in
t.animation = nil
}
}
func sendMessage(draft: String) {
print("The message: \(draft)")
}
}
CodePudding user response:
It is possible to prevent keyboard hiding using a somewhat "hacky" solution, combing re-focus of field together with disable animation.
struct ChatView {
enum Field: String, Hashable {
case chat
}
@State var draft = ""
@FocusState var focusedField: Field?
var body: some View {
VStack {
// messages view omitted
TextField(
"Chat...",
text: $draft
)
.submitLabel(.send)
.onSubmit {
if !draft.isEmpty {
sendMessage()
// We just lost focus because "return" key was pressed
// we re-fucus
focusedField = .chat
}
}
Button("Send") {
sendMessage()
}
}
// Prevent hacky keyboard hide animation
.transaction { $0.animation = nil }
}
func sendMessage() {
// impl omitted, sending message `draft` using some dependency.
}
}