You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SecureField在系统密码弹窗显示时按下Enter不触发onSubmit的解决方法

问题解决方法

问题根源在于系统密码自动填充弹窗会拦截Enter键的事件传递,导致SwiftUI原生SecureField的onSubmit无法触发。以下是两种可行的解决方式:

方案一:基于UIKit包装自定义SecureField

通过UIKit的UITextField包装实现,利用其代理方法稳定捕获回车事件,不受系统弹窗影响:

import SwiftUI
import UIKit

struct CustomSecureField: UIViewRepresentable {
    let placeholder: String
    @Binding var text: String
    let onSubmit: () -> Void
    
    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField()
        textField.placeholder = placeholder
        textField.isSecureTextEntry = true
        textField.textContentType = .password
        textField.delegate = context.coordinator
        // 可根据你的FTextFieldStyle调整样式,比如去掉边框、设置字体等
        textField.borderStyle = .none
        return textField
    }
    
    func updateUIView(_ uiView: UITextField, context: Context) {
        uiView.text = text
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }
    
    class Coordinator: NSObject, UITextFieldDelegate {
        let parent: CustomSecureField
        
        init(parent: CustomSecureField) {
            self.parent = parent
        }
        
        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            parent.onSubmit()
            textField.resignFirstResponder()
            return true
        }
    }
}

替换原有的SecureField使用:

CustomSecureField(placeholder: "Password", text: $password, onSubmit: {
    if canLogin() {
        login()
    } else {
        focusedField = .username
    }
})
.focused($focusedField, equals: .password)

方案二:全局监听回车事件(纯SwiftUI实现)

通过监听系统键盘按键通知,结合焦点判断触发回调(iOS 15+适用):

SecureField("Password", text: $password)
    .textContentType(.password)
    .textFieldStyle(FTextFieldStyle())
    .focused($focusedField, equals: .password)
    .onReceive(NotificationCenter.default.publisher(for: UIApplication.keyUpNotification)) { notification in
        guard let key = notification.userInfo?[UIApplication.keyboardUserInfoKey] as? UIKey,
              key.keyCode == .returnOrEnter,
              focusedField == .password else {
            return
        }
        if canLogin() {
            login()
        } else {
            focusedField = .username
        }
    }

方案对比

  • 方案一:兼容性更强,样式可灵活匹配原有需求,适合需要稳定兼容多版本的场景。
  • 方案二:代码更简洁,无需额外包装组件,但依赖iOS 15+的API,低版本需额外适配按键判断逻辑。

内容的提问来源于stack exchange,提问作者Peter Lapisu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 22:35:15