如何在 SwiftUI 中将 .onSubmit() 与垂直 TextField 一起使用?

And*_*Kat 6 ios swift swiftui

我试图TextField在`SwiftUI 中垂直增长,但也让软件键盘具有自定义提交方法。

这使用了 iOS 16 的新功能TextFields,能够将轴作为其增长方式的参数。请参阅此处的文档:https ://developer.apple.com/documentation/swiftui/textfield/init(_:text:axis:)-8rujz 。

ContentView这是显示设置的示例。

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当您运行此程序时,您可以看到TextField正确的垂直增长,但即使您有自定义提交标签,按 iOS 上软件键盘中的蓝色“发送”按钮也只会插入换行符,而不是触发.onSubmit

使用硬件键盘时,按回车键确实会运行 中的代码.onSubmit,因此这似乎只是软件键盘的限制。

ej5*_*607 5

我已将这篇文章中的出色建议应用于您的问题。这对你有用吗?

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)
                }
            }
                            
    }
}
Run Code Online (Sandbox Code Playgroud)

}


nil*_*lue 4

更新:考虑使用像这样表示的UITextView。以下解决方案可能不适用于所有情况。

修改了以前的 解决方案,因为在我的例子中,它们导致TextField来回跳转,在按回车键(或完成)后添加并立即删除新行。如果您遇到类似的行为,我将以前的解决方案与这个想法结合起来,并且它有所帮助。因此,基本上,您需要找出“\n”是否被插入到某处,并在消息本身更改之前切换FocusState

struct ContentView: View {

    @State var message: String = ""
    @FocusState private var isFocused: Bool
    
    var body: some View {
        VStack {
            TextField("Placeholder",
                      text: Binding(
                        get: { message },
                        set:
                            { (newValue, _) in
                                if let _ = newValue.lastIndex(of: "\n") {
                                    isFocused = false
                                } else {
                                    message = newValue
                                }
                            }
                      ), axis: .vertical)
                .submitLabel(.done)
                .focused($isFocused)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)