swift - SwiftUI 更改 SecureField 掩码字符
问题描述
MacOS 11 上的 SwiftUI
目标是让 SwiftUI SecureField 显示与默认项目符号 (••••••) 不同的 Unicode 字符,例如表情符号、随机生成的字符等。目标的一个重要部分是实际的文本输入by user 是完全可编辑和保留的,并且可以在@State
变量中访问,并且仅显示掩码字符,但我不介意它是通过 TextField 或其他一些 View 实现的。
例如,香草 SecureField 项目符号:
struct ContentView : View {
@State var password : String = ""
var body: some View {
VStack {
SecureField("Password", text: $password)
Button("Transmogrify!") {}
}.padding()
}
}
结果是:
目标是实现与 SecureField 相同的行为,但显示不同的字符,如下所示:
到目前为止,我还没有想出一个有效的代码示例。我曾尝试将纯文本TextField
与显式结合使用Binding<String>
来尝试控制底层文本get
/set
但由于绑定的性质会影响最终存储在password
解决方案
你可以用代理来做
import SwiftUI
//Shows a sample use
@available(iOS 15.0, macOS 12.0, *)
struct SecureParentView: View{
@State var text: String = "secure"
var body: some View{
VStack{
Text(text)
MySecureFieldView(text: $text)
}
}
}
//The custom field
@available(iOS 15.0, macOS 12.0, *)
struct MySecureFieldView: View {
@Binding var text: String
//The proxy handles the masking
var proxy: Binding<String>{
Binding(get: {
return text.map { _ in "\u{272A}" }.joined()
}, set: { value in
//Not needed here because the TextField is focused
})
}
@FocusState private var focusedField: Int?
var body: some View {
//This is for size. The 3 layers have to match so the cursor doesn't look off
Text(text).lineLimit(1)
.opacity(0)
//Put a true secure field on top that has invisible text/dots
.overlay(
SecureField("actual", text: $text)
.foregroundColor(Color.clear)
.focused($focusedField, equals: 1)
.minimumScaleFactor(0.2)
)
.background(
//This will sit on below but will look like it is on top
//It will reduce in size to match lettering
Text(proxy.wrappedValue)
.lineLimit(1)
.minimumScaleFactor(0.2)
.foregroundColor(Color(UIColor.label))
.opacity(1)
)
.foregroundColor(Color(UIColor.clear))
.onTapGesture {
focusedField = 1
}
}
}
@available(iOS 15.0, macOS 12.0, *)
struct SecureParentView_Previews: PreviewProvider {
static var previews: some View {
SecureParentView()
}
}
推荐阅读
- objective-c - Objective-C 中的布尔类型有什么区别?
- reactjs - 我怎样才能用 sass 做到这一点并做出反应?
- postsharp - 让 PostSharp 6.0.32 和 Log4Net 2.0.0 在自定义级别登录
- python - 基于模式搜索重命名多个列
- javascript - 重定向到我的主页网址后,如何使用 Javascript/Jquery 实现自动点击?
- python - 在数据框中转换嵌套字典?
- r - data.table:使用 lapply 和 .SD 创建多个列
- asterisk - Asterisk 13.x 和 fail2ban 正则表达式字符串
- sql-server - FULL OUTER JOIN 的替代方案
- android - 为什么在设备锁定时调用 onStartInputView()?