macOS应用开发中SwiftUI是否有textFieldShouldReturn的等效实现?
macOS SwiftUI 监听TextField回车键按下的实现方案
SwiftUI提供了多个层级的实现方案,可根据你需要兼容的系统版本选择:
1. macOS 12+ 原生最简方案(推荐)
使用SwiftUI原生的onSubmit修饰符,等效于UIKit的textFieldShouldReturn基础用法,按下回车键时自动触发闭包内的逻辑:
struct ContentView: View { @State private var inputText = "" var body: some View { TextField("请输入内容", text: $inputText) .onSubmit { // 此处写入按下回车后需要执行的逻辑 print("用户输入内容:\(inputText)") } } }
如果需要控制按下回车后是否结束编辑(收起键盘),可以配合focused修饰符实现:
struct ContentView: View { @State private var inputText = "" @FocusState private var isInputFocused: Bool var body: some View { TextField("请输入内容", text: $inputText) .focused($isInputFocused) .onSubmit { print("用户输入内容:\(inputText)") // 若不需要结束编辑,注释下方代码即可 isInputFocused = false } } }
2. 兼容 macOS 10.15+ 通用方案
如果需要适配macOS 12以下的系统版本,可以通过监听NSTextField的编辑结束通知实现:
import SwiftUI import Combine struct ContentView: View { @State private var inputText = "" @FocusState private var isInputFocused: Bool var body: some View { TextField("请输入内容", text: $inputText) .focused($isInputFocused) .onReceive(NotificationCenter.default.publisher(for: NSControl.textDidEndEditingNotification)) { notification in guard let textField = notification.object as? NSTextField, isInputFocused else { return } // 执行回车后的逻辑 print("用户输入内容:\(inputText)") } } }
3. 完全自定义回车行为方案
如果你需要完全复现textFieldShouldReturn的返回值控制逻辑(比如拦截默认回车事件、自定义是否结束编辑),可以通过NSViewRepresentable封装原生NSTextField实现:
struct CustomTextField: NSViewRepresentable { @Binding var text: String // 回车闭包返回true表示允许结束编辑,返回false表示保持编辑状态 let onReturn: () -> Bool func makeNSView(context: Context) -> NSTextField { let textField = NSTextField() textField.delegate = context.coordinator return textField } func updateNSView(_ nsView: NSTextField, context: Context) { nsView.stringValue = text } func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, NSTextFieldDelegate { let parent: CustomTextField init(_ parent: CustomTextField) { self.parent = parent } func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool { // 监听回车事件 if commandSelector == #selector(NSResponder.insertNewline(_:)) { let shouldEndEditing = parent.onReturn() if shouldEndEditing { textView.window?.makeFirstResponder(nil) } // 拦截系统默认回车行为 return true } return false } func controlTextDidChange(_ obj: Notification) { guard let textField = obj.object as? NSTextField else { return } parent.text = textField.stringValue } } } // 使用示例 struct ContentView: View { @State private var inputText = "" var body: some View { CustomTextField(text: $inputText) { print("用户输入内容:\(inputText)") // 设为false时按下回车不会失去焦点 return true } .frame(width: 250, height: 30) } }
内容的提问来源于stack exchange,提问作者WilliamD47
相关产品推荐
相关产品推荐

