在 SwiftUI 中为 SecureField 切换 isSecureTextEntry

toggle isSecureTextEntry in SwiftUI for SecureField

我想实现在 SecureField 中显示和隐藏密码的功能。 下面是 SecureField 的代码 我添加了按钮,该按钮将被检测到以显示和隐藏 SecureField 中的文本。 但是 swiftUI 没有类似于 isSecureTextEntry 的功能 除了在 TextfieldSecureField here

之间切换之外,还有其他方法吗?
SecureField(placeholder, text: $textValue, onCommit: {
    onReturn?()
})
.onTapGesture {
    onBegin?()
}
.keyboardType(keyboardType)
.font(Font.label.bodyDefault)
.disableAutocorrection(true)
.frame(maxWidth: .infinity, maxHeight: 40)
.padding(.leading)

这并不像它应该的那样简单。其中一个答案非常接近,但它并没有完全涵盖所有内容,因为它对 @FocusState 的实现很差。 iOS 15 确实使这个字段更容易构造,因为有两个键:1. 使用 .opacity() 显示和隐藏字段, 2. 使用 @FocusState 在字段之间进行无缝过渡两个领域。此方法的唯一缺点是为了实现无缝转换,您必须将键盘限制为仅支持 ASCII 兼容字符,因此某些语言被排除在外,例如俄语。

struct CustomSecureField: View {
    
    @FocusState var focused: focusedField?
    @State var showPassword: Bool = false
    @Binding var password: String
    
    var body: some View {
        HStack {
            ZStack(alignment: .trailing) {
                TextField("Password", text: $password)
                    .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: $password)
                    .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()
                })
            }
        }
    }
    // Using the enum makes the code clear as to what field is focused.
    enum focusedField {
        case secure, unSecure
    }
}