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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 11:22:18