SwiftUI中无需UIApplication.shared关闭键盘的方法(含应用扩展场景)
因为应用扩展无法访问UIApplication.shared,可以用以下几种原生SwiftUI或适配性方法实现键盘关闭:
方法1:使用@FocusState(推荐)
这是SwiftUI 3.0+提供的原生焦点管理API,完全不需要依赖UIKit的全局对象,非常适合应用扩展场景。
步骤:
- 定义一个
@FocusState属性,标记当前是否有输入框处于焦点状态 - 将输入控件(如
TextField、SecureField)与这个属性绑定 - 需要关闭键盘时,将该属性设为
nil即可
示例代码:
struct ExtensionContentView: View { @State private var inputText = "" @FocusState private var isInputFocused: Bool var body: some View { VStack { TextField("输入内容", text: $inputText) .focused($isInputFocused) Button("关闭键盘") { isInputFocused = false } } } }
方法2:通过UIViewRepresentable包装实现
如果需要支持更低版本的SwiftUI,或者需要更灵活的控制,可以通过包装UIKit的UIResponder能力来实现:
创建一个自定义的DismissKeyboardViewModifier,利用UIView的endEditing(_:)方法关闭键盘:
struct DismissKeyboardViewModifier: ViewModifier { func body(content: Content) -> some View { content .background( UIViewRepresentable { uiView in let tapGesture = UITapGestureRecognizer(target: uiView, action: #selector(uiView.endEditing(_:))) uiView.addGestureRecognizer(tapGesture) } ) } } extension View { func dismissKeyboardOnTap() -> some View { self.modifier(DismissKeyboardViewModifier()) } } // 使用方式 struct ExtensionContentView: View { @State private var inputText = "" var body: some View { VStack { TextField("输入内容", text: $inputText) } .dismissKeyboardOnTap() } }
这个方法通过给视图添加点击手势,触发endEditing(true)来关闭当前所有活跃的键盘,同样不需要访问UIApplication。
方法3:利用NotificationCenter(适合特定场景)
如果需要在某个全局事件触发时关闭键盘,可以通过发送自定义通知,在输入控件的代理中监听并关闭:
// 定义通知名称 extension Notification.Name { static let dismissKeyboard = Notification.Name("DismissKeyboardNotification") } // 包装TextField并监听通知 struct DismissibleTextField: UIViewRepresentable { @Binding var text: String func makeUIView(context: Context) -> UITextField { let textField = UITextField() textField.delegate = context.coordinator NotificationCenter.default.addObserver(context.coordinator, selector: #selector(Coordinator.dismissKeyboard), name: .dismissKeyboard, object: nil) return textField } func updateUIView(_ uiView: UITextField, context: Context) { uiView.text = text } func makeCoordinator() -> Coordinator { Coordinator(text: $text) } class Coordinator: NSObject, UITextFieldDelegate { @Binding var text: String init(text: Binding<String>) { _text = text } func textFieldDidChangeSelection(_ textField: UITextField) { text = textField.text ?? "" } @objc func dismissKeyboard() { textField.resignFirstResponder() } } } // 使用时发送通知关闭键盘 Button("关闭键盘") { NotificationCenter.default.post(name: .dismissKeyboard, object: nil) }
内容的提问来源于stack exchange,提问作者Fitzgerald Afful
相关产品推荐
相关产品推荐

