SwiftUI中如何实现TextField的Token Key部分掩码效果
SwiftUI实现Token输入框的部分掩码效果
SecureField本身仅支持完全掩码,无法实现“显示前N个字符+其余掩码”的需求,因此需要自定义输入组件来实现。以下是具体实现方案:
步骤1:创建自定义部分掩码输入框
通过UIViewRepresentable包装UITextField,分离真实输入内容和显示内容:
import SwiftUI struct PartialMaskTextField: UIViewRepresentable { @Binding var text: String let placeholder: String let visibleCharacterCount: Int // 可自定义显示的前置字符数量 let maskCharacter: Character = "*" func makeUIView(context: Context) -> UITextField { let textField = UITextField() textField.placeholder = placeholder textField.delegate = context.coordinator textField.textColor = .blue textField.backgroundColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1) textField.layer.cornerRadius = 6 textField.padding = UIEdgeInsets(top: 4, left: 4, bottom: 4, right: 4) return textField } func updateUIView(_ uiView: UITextField, context: Context) { uiView.text = maskedText(from: text) } func makeCoordinator() -> Coordinator { Coordinator(self) } class Coordinator: NSObject, UITextFieldDelegate { let parent: PartialMaskTextField init(_ parent: PartialMaskTextField) { self.parent = parent } func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { // 计算真实输入文本并更新绑定值 let realNewText = (parent.text as NSString).replacingCharacters(in: range, with: string) parent.text = realNewText // 更新显示为掩码后的文本 textField.text = parent.maskedText(from: realNewText) return false } } private func maskedText(from realText: String) -> String { guard realText.count > visibleCharacterCount else { return realText } let visiblePart = String(realText.prefix(visibleCharacterCount)) let maskedPart = String(repeating: maskCharacter, count: realText.count - visibleCharacterCount) return visiblePart + maskedPart } } // 给UITextField添加内边距的扩展 extension UITextField { var padding: UIEdgeInsets { get { .zero } set { leftView = UIView(frame: CGRect(x: 0, y: 0, width: newValue.left, height: frame.height)) leftViewMode = .always rightView = UIView(frame: CGRect(x: 0, y: 0, width: newValue.right, height: frame.height)) rightViewMode = .always } } }
步骤2:替换原SecureField
在你的SettingsView中,将原SecureField替换为自定义的PartialMaskTextField:
private var authTokenField: some View { HStack { PartialMaskTextField( text: $authToken, placeholder: "Enter your auth token here", visibleCharacterCount: 3 // 这里设置要显示的前置字符数 ) // ... 保留原有的其他代码 ... } .padding().frame(maxWidth: .infinity, alignment: .leading) }
说明
- 真实的Token内容会正常存储在
authToken变量中(绑定@AppStorage),仅显示时做掩码处理 - 可通过
visibleCharacterCount参数自定义显示的前置字符数量 - 输入过程中始终保持掩码显示,不会暴露完整Token
内容的提问来源于stack exchange,提问作者P_n
相关产品推荐
相关产品推荐

