swe*_*iya 2 swiftui securefield
我想实现在 SecureField 中显示和隐藏密码的功能。下面是 SecureField 的代码,我添加了按钮,将检测到该按钮以显示和隐藏 SecureField 中的文本。但是 swiftUI 没有类似于isSecureTextEntry 的功能 除了在 Textfield 和 SecureField 之间切换之外还有其他方法吗
SecureField(placeholder, text: $textValue, onCommit: {
onReturn?()
})
.onTapGesture {
onBegin?()
}
.keyboardType(keyboardType)
.font(Font.label.bodyDefault)
.disableAutocorrection(true)
.frame(maxWidth: .infinity, maxHeight: 40)
.padding(.leading)
Run Code Online (Sandbox Code Playgroud)
这并不像应有的那么简单。其中一个答案非常接近,但它并不能完全涵盖所有内容,因为它的@FocusState. iOS 15 确实让这个字段更容易构建,因为有两个关键:1. using.opacity()显示和隐藏字段,2. using@FocusState在两个字段之间进行无缝过渡。此方法的唯一缺点是为了实现无缝转换,您必须将键盘限制为仅兼容 ASCII 的字符,因此某些语言被排除在外,例如俄语。
以下代码已更新,以解决评论中提出的 SecureField 重置问题。
struct CustomSecureField: View {
@FocusState private var focused: focusedField?
@State private var showPassword: Bool = false
@State private var internalPassword: String
@State private var keepInternalPassword = false
@Binding var password: String
init(password: Binding<String>) {
_internalPassword = State(initialValue: password.wrappedValue)
_password = password
}
var body: some View {
HStack {
ZStack(alignment: .trailing) {
TextField("Password", text: $internalPassword)
.focused($focused, equals: .unSecure)
.autocapitalization(.none)
.disableAutocorrection(true)
// This is needed to remove suggestion bar, otherwise swapping between
// fields will change keyboard height and be distracting to user.
.keyboardType(.alphabet)
.opacity(showPassword ? 1 : 0)
SecureField("Password", text: $internalPassword)
.focused($focused, equals: .secure)
.autocapitalization(.none)
.disableAutocorrection(true)
.opacity(showPassword ? 0 : 1)
Button(action: {
showPassword.toggle()
focused = focused == .secure ? .unSecure : .secure
}, label: {
Image(systemName: self.showPassword ? "eye.slash.fill" : "eye.fill")
.padding()
})
.onChange(of: focused, initial: false) { oldValue, newValue in
// This prevents sets the value for keepInternalPassword after a focus change
// Both values need to be compared because we need to insure the value was
// changed from .unsecure
if newValue == .secure && oldValue == .unSecure {
keepInternalPassword = true
print("focus onchange keepInternalPassword = true")
}
}
.onChange(of: internalPassword, initial: false) { oldValue, newValue in
// if the old value is being kept, the internal password is reset
// to that value here
if keepInternalPassword {
DispatchQueue.main.async {
keepInternalPassword = false
internalPassword = oldValue
}
return
}
// otherwise, update password
password = internalPassword
}
}
}
}
// Using the enum makes the code clear as to what field is focused.
enum focusedField {
case secure, unSecure
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4414 次 |
| 最近记录: |