So basically I created a multiline textField, but pressing onSubmit won't work at all, I rather it submit when double pressing return or something similar. if there is a way to avoid collapsing the keyboard when submitting instead of using multiline I would be grateful to be told how :)
2 Answers
This is the workaround that I've used:
struct SwiftUIView: View {
@State var text: String = ""
var body: some View {
TextField("text", text: $text, axis: .vertical)
.frame(width: 200, height: 200)
.multilineTextAlignment(.leading)
.textFieldStyle(.roundedBorder)
.font(.title)
.onChange(of: text) { newValue in
guard let newValueLastChar = newValue.last else { return }
if newValueLastChar == "\n" {
text.removeLast()
hideKeyboard()
}
}
}
}
Being hideKeyboard a function defined in an extension of View:
extension View {
func hideKeyboard() {
UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}

- 81
- 4
-
-
This won't work if the user is editing in the middle of the string and hits the done button as the new line character won't be the last one – SeanR Apr 21 '23 at 05:06
In my case I wanted the tab key to work so that the next field is focusses when the user presses tab. That works out of the box when using TextField("User name (email address)", text: $username)
, but it stops working when using , axis: ...
.
This workaround fixes it for me. It compares the old value with the new, ensuring that (a) the string grew by just one character and (b) that the new string has one \t
more than the old string. That ensures that the user can tab anywhere in the field and should offer reasonable protection when the user pastes texts into the field that could contain tab characters.
TextField("Title", text: $title, axis: .vertical)
.focused($focus, equals: .title)
.onChange(of: title) { [title] newValue in
let oldTabCount = title.filter { $0 == "\t" }.count
let newTabCount = newValue.filter { $0 == "\t" }.count
if newValue.count == (title.count + 1) && newTabCount == (oldTabCount + 1) {
// Reset title to previous value (without the new tab)
self.title = title
self.focus = .content
}
}
TextField("Content", text: $content)
.focused($focus, equals: .content)
The focus
var is defined as @FocusState var focus: FocusOption?
and FocusOption
is a simple enum:
enum FocusOption: Equatable {
case title
case content
}
Enjoy!

- 42,912
- 19
- 126
- 165