MacOS 11下SwiftUI如何修改SecureField默认掩码字符
自定义掩码SecureField实现方案
实现思路
拆分真实密码存储和前台展示逻辑,完全避免绑定修改真实密码值:
- 用两个状态变量分别存储真实密码原文和前台展示的掩码文本
- 普通TextField绑定到掩码文本,监听输入事件同步更新真实密码,同时将展示内容替换为指定长度的自定义掩码
- 真实密码可通过专属状态变量正常访问、编辑,不受掩码展示影响
完整代码示例
import SwiftUI struct CustomSecureField: View { // 对外暴露的真实密码绑定,父视图可直接读写访问 @Binding var realPassword: String // 自定义掩码字符,支持任意Unicode字符,包括Emoji、特殊符号、随机生成字符 let maskCharacter: String = "🔒" // 内部控制前台展示的掩码文本 @State private var displayText: String = "" var body: some View { TextField("Password", text: $displayText) .onChange(of: displayText) { newValue in let deltaLength = newValue.count - realPassword.count if deltaLength > 0 { // 新增输入:取新输入的字符追加到真实密码 let newInput = newValue.suffix(deltaLength) realPassword.append(contentsOf: newInput) } else if deltaLength < 0 { // 删除操作:从真实密码中删除对应长度的字符 realPassword.removeLast(-deltaLength) } // 刷新展示内容为对应长度的掩码,完全覆盖实际输入 displayText = String(repeating: maskCharacter, count: realPassword.count) } .onAppear { // 初始化时同步已有真实密码的掩码展示 displayText = String(repeating: maskCharacter, count: realPassword.count) } } } // 调用示例,和原生SecureField用法完全一致 struct ContentView : View { @State var password : String = "" var body: some View { VStack { CustomSecureField(realPassword: $password) Button("Transmogrify!") { // 可直接访问password变量获取真实输入内容 print("真实输入密码:\(password)") } }.padding() } }
补充说明
如果需要支持光标在文本中间插入、删除的高级编辑场景,可基于NSViewRepresentable封装原生NSTextField实现:通过NSTextField的代理方法监听输入,直接修改展示属性,内部保留真实输入值即可。
内容的提问来源于stack exchange,提问作者bochko
相关产品推荐
相关产品推荐

