skip to Main Content

I’m trying to have a vertically growing TextField in `SwiftUI but also have the software keyboard have a custom submission method.

This uses the new functionality of iOS 16’s TextFields being able to take an axis as an argument for which way it should grow. See the docs here: https://developer.apple.com/documentation/swiftui/textfield/init(_:text:axis:)-8rujz.

Here’s a sample ContentView showing the setup.

struct ContentView: View {

    @State var message: String = ""
    var body: some View {
        
        VStack {
            Text("Try to submit this using the blue send button on the software keyboard")
            TextField("Placeholder", text: $message, axis: .vertical)
                .onSubmit {
                    print("submission!")
                }
            .submitLabel(.send)
        }
    }
}

When you run this, you can see the TextField properly grows vertically, but even when you have a custom submission label, pressing the blue "send" button in the software keyboard on iOS just inserts a newline, rather than firing the .onSubmit

When using a hardware keyboard, pressing the return does run the code in .onSubmit, so this seemingly just a limitation of the software keyboard.

2

Answers


  1. I’ve applied the excellent advice from this post to your question. Would this work for you?

    struct ContentView: View {
    
    @State var message: String = ""
    var body: some View {
        
        VStack {
            Text("Try to submit this using the blue send button on the software keyboard")
            TextField("Placeholder", text: $message, axis: .vertical)
                .submitLabel(.send)
                .onChange(of: message) { newValue in
                    guard let newValueLastChar = newValue.last else { return }
                    if newValueLastChar == "n" {
                        message.removeLast()
                        print("submission!")
                        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
                    }
                }
                                
        }
    }
    

    }

    Login or Signup to reply.
  2. ej5607’s answer won’t work if the user is editing partway through the string and hits the Send button. I’ve modified it to fix that and also use the @FocusState rather than calling in to UIApplication.

    struct ContentView: View {
        
        @State var message: String = ""
        enum Field: Int, Hashable {
            case message
        }
        @FocusState private var focusedField: Field?
    
        var body: some View {
        
            VStack {
                Text("Try to submit this using the blue send button on the software keyboard")
                TextField("Placeholder", text: $message, axis: .vertical)
                    .submitLabel(.send)
                    .focused($focusedField, equals: .message)
                    .onChange(of: message) { newValue in
                        if let newLineIndex = message.lastIndex(of: "n") {
                            message.remove(at: newLineIndex)
                            print("submission!")
                            focusedField = nil
                        }
                    }
                }
            }
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search