SwiftUI SecureField:如何实现与 UIKit 中相同的字符模糊行为?
SwiftUI SecureField: How to achieve the same character obscuring behaviour as in UIKit?
我的问题是 SecureField
在 SwiftUI 中根本不显示用户在任何时候输入的字符,它只是在输入每个字符时直接显示“•”符号 - 而在 UIKit 中, UITextField
(isSecureTextEntry = true
)显示最新的字符一秒钟,然后将其隐藏在“•”后面。
我公司的用户体验测试人员要求我恢复“旧行为”——但这种行为似乎并不属于任何 public API.
有趣的是,这也适用于使用 UIViewRepresentable
注入 SwiftUI 的 UITextField
自定义 类 - 它们以上述“SwiftUI 方式”运行。所以在 SwiftUI 中针对所有安全 UITextField
行为进行了一些上下文行为修改?我必须将我的 SwiftUI 表单完全重写为完整的 UIViewController
才能恢复行为(使用安全 UITextFields do 模态推送的 UIViewControllers 表现出所需的行为。)
这是 SwiftUI 中的一种副业错误吗?我在 iOS13 和 14 中都看到了 SwiftUI 的相同情况。有人看到了解决方法或解决方案吗?
-编辑-
在下面 @Asperi 的精彩解释之后,我注意到我使用 UIViewRepresentable
注入 SwiftUI 的 UITextField
自定义 类 通过在 [=] 中不必要地设置文本绑定来强制执行此行为19=] 呼叫。使用协调器仅处理文本逻辑解决了我使用此方法时的问题。
观察到的效果是由于立即应用于绑定字符串状态和立即 react/rebuild 视图。
为了实现所需的行为,我们需要以某种方式推迟状态更新,从而让 SecuredField/UITextField 有机会在不与状态同步的情况下更新自身。
这是一个可能的方向的演示(它不是理想的,但可以走的路)。使用 Xcode 12.1 / iOS 14.1.
测试
struct DemoSecureFieldView: View {
@State private var password = "demo"
var textBinding: Binding<String> {
Binding(get: { password },
set: { value in
// more logic can be added to delay _only_ if new symbol added,
// and force apply if next symbol came fast
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
password = value
}
}
)
}
var body: some View {
VStack {
SecureField("Placeholder", text: textBinding)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
}.background(Color.pink)
}
}
我的问题是 SecureField
在 SwiftUI 中根本不显示用户在任何时候输入的字符,它只是在输入每个字符时直接显示“•”符号 - 而在 UIKit 中, UITextField
(isSecureTextEntry = true
)显示最新的字符一秒钟,然后将其隐藏在“•”后面。
我公司的用户体验测试人员要求我恢复“旧行为”——但这种行为似乎并不属于任何 public API.
有趣的是,这也适用于使用 UIViewRepresentable
注入 SwiftUI 的 UITextField
自定义 类 - 它们以上述“SwiftUI 方式”运行。所以在 SwiftUI 中针对所有安全 UITextField
行为进行了一些上下文行为修改?我必须将我的 SwiftUI 表单完全重写为完整的 UIViewController
才能恢复行为(使用安全 UITextFields do 模态推送的 UIViewControllers 表现出所需的行为。)
这是 SwiftUI 中的一种副业错误吗?我在 iOS13 和 14 中都看到了 SwiftUI 的相同情况。有人看到了解决方法或解决方案吗?
-编辑-
在下面 @Asperi 的精彩解释之后,我注意到我使用 UIViewRepresentable
注入 SwiftUI 的 UITextField
自定义 类 通过在 [=] 中不必要地设置文本绑定来强制执行此行为19=] 呼叫。使用协调器仅处理文本逻辑解决了我使用此方法时的问题。
观察到的效果是由于立即应用于绑定字符串状态和立即 react/rebuild 视图。
为了实现所需的行为,我们需要以某种方式推迟状态更新,从而让 SecuredField/UITextField 有机会在不与状态同步的情况下更新自身。
这是一个可能的方向的演示(它不是理想的,但可以走的路)。使用 Xcode 12.1 / iOS 14.1.
测试struct DemoSecureFieldView: View {
@State private var password = "demo"
var textBinding: Binding<String> {
Binding(get: { password },
set: { value in
// more logic can be added to delay _only_ if new symbol added,
// and force apply if next symbol came fast
DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
password = value
}
}
)
}
var body: some View {
VStack {
SecureField("Placeholder", text: textBinding)
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding()
}.background(Color.pink)
}
}