显示/隐藏密码 - 如何添加此功能?

Moe*_*rdi 8 xcode swift swiftui

我已经浏览了论坛,但我看到了不同的答案,尤其是来自旧 Xcode 版本的答案。

我只是在输入了我在这张照片中的代码后才决定添加这个。

我怎么能这样做呢?我想要在密码字段上实现“眼球”切换。

Osc*_*ell 19

对于那些仍在寻找此问题的简单解决方案的人(需要 iOS 15 才能使用 swiftUI 3):

通过 swiftUI 3 中引入的新功能@FocusState,可以在更改状态时保持焦点和键盘打开。

通过使用opacity修饰符而不是有条件地在 SecureField 和 TextField 之间进行更改,焦点可以在两者之间跳转,而不会出现键盘问题。

这允许您使用 ZStack 中包含的眼睛按钮在显示和隐藏密码之间切换。

import SwiftUI

struct SecureTextFieldWithReveal: View {

@FocusState var focus1: Bool
@FocusState var focus2: Bool
@State var showPassword: Bool = false
@State var text: String = ""

var body: some View {
    HStack {
        ZStack(alignment: .trailing) {
            TextField("Password", text: $text)
                .modifier(LoginModifier())
                .textContentType(.password)
                .focused($focus1)
                .opacity(showPassword ? 1 : 0)
            SecureField("Password", text: $text)
                .modifier(LoginModifier())
                .textContentType(.password)
                .focused($focus2)
                .opacity(showPassword ? 0 : 1)
            Button(action: {
                showPassword.toggle()
                if showPassword { focus1 = true } else { focus2 = true }
            }, label: {
                Image(systemName: self.showPassword ? "eye.slash.fill" : "eye.fill").font(.system(size: 16, weight: .regular))
                    .padding()
            })
        }
    }
}
}
Run Code Online (Sandbox Code Playgroud)

密码字段隐藏

密码字段显示

这是以下代码LoginModifier

import SwiftUI

struct LoginModifier: ViewModifier {

var borderColor: Color = Color.gray

func body(content: Content) -> some View {
    content
        .disableAutocorrection(true)
        .autocapitalization(.none)
        .padding()
        .overlay(RoundedRectangle(cornerRadius: 10).stroke(borderColor, lineWidth: 1))
}
}
Run Code Online (Sandbox Code Playgroud)

我使用此方法遇到的唯一问题是,SecureField如果您开始输入,重新获得焦点时会自动清除已输入的任何文本。这似乎是苹果的设计选择。


Vah*_*yan 11

在此处输入图片说明您可以简单地使用此视图而不是SecureField. 它里面有眼睛图标,所以在大多数情况下你不需要关心任何事情。

struct SecureInputView: View {
    
    @Binding private var text: String
    @State private var isSecured: Bool = true
    private var title: String
    
    init(_ title: String, text: Binding<String>) {
        self.title = title
        self._text = text
    }
    
    var body: some View {
        ZStack(alignment: .trailing) {
            if isSecured {
                SecureField(title, text: $text)
            } else {
                TextField(title, text: $text)
            }
            Button(action: {
                isSecured.toggle()
            }) {
                Image(systemName: self.isSecured ? "eye.slash" : "eye")
                    .accentColor(.gray)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

将此视图复制粘贴到您的应用程序中,而SecureField不仅仅是使用SecureInputView.

例子: SecureInputView("Password", text: $viewModel.password)

  • 此解决方案存在 3 个问题。1. 如果您输入文本,点击显示密码,点击隐藏密码,然后再次输入文本,secureField 将被清除。2. 当点击显示密码时,键盘将被关闭。3. 使用 ZStack 将在按钮下方写入文本。 (11认同)

Asp*_*eri 6

可能的方法是显示加入一个存储的 TextField 或 SecureField,如下面的演示所示:

struct DemoShowPassword: View {
    @State private var showPassword: Bool = false
    @State private var password = "demo"

    var body: some View {
        VStack {
            if showPassword {
                TextField("Placeholer", text: $password)
            } else {
                SecureField("Placeholder", text: $password)
            }
            Button("toggle") {
                self.showPassword.toggle()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这种方法有问题。如果显示键盘并且您按下切换按钮,它将关闭键盘,因为现在显示不同的字段 (3认同)

小智 5

恐怕这里的大多数答案都没有提到从 切换到SecureFieldTextField降低安全性。SecureField本质上,根据 Apple 文档,只是TextField用户输入被屏蔽的地方 [1]。然而,SecureField它还做了另一项工作——它防止使用第三方键盘(键盘扩展),从而保护用户的安全和隐私。

理想的解决方案是拥有既“安全”又具有mask()/unmask()方法的输入字段。不幸的是,我发现的唯一建议是,当您想要按照其他答案建议的方式实现取消屏蔽时,至少完全阻止应用程序中的第三方键盘 [2]:

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, shouldAllowExtensionPointIdentifier extensionPointIdentifier: UIApplication.ExtensionPointIdentifier) -> Bool {
        return extensionPointIdentifier != UIApplication.ExtensionPointIdentifier.keyboard
    }
}
@main
struct MyApplication: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

还应该提到它UIApplicationDelegate是 UIKit 的一部分,而不是 SwiftUI。目前还没有用于相同目的的“原生”SwiftUI,尽管上述方法目前工作正常。

  1. https://developer.apple.com/documentation/swiftui/securefield
  2. https://www.secure.pl/en/third-party-iphone-keyboards-vs-your-ios-application-security/