在 UITextView 中设置密码保护

Set password protection in UITextView

我可以在 UITextView 中用 * 或任何其他符号隐藏密码吗?我需要使用 UITextView 而不是 UITextField。我想隐藏textView的所有字符。

使用 UITextView 可以让您自己完成屏蔽文本的整个工作。出于安全原因,您还需要确保禁用复制。设置你的 delegate 属性 并在这些行上处理这个问题:

var originalText: String?

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    originalText = ((originalText ?? "") as NSString).replacingCharacters(in: range, with: text)
    return true
}

func textViewDidChange(_ textView: UITextView) {
    textView.text = String(repeating: "*", count: (textView.text ?? "").count)
}

如果您需要检索输入的实际文本的值,请使用 originalText 属性.

为密码字符串创建一个全局变量。

var passwordString = ""

然后像这样设置 UITextView 的委托:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    passwordString = ((passwordString ?? "") as NSString).replacingCharacters(in: range, with: text)
    return true
}

func textViewDidChange(_ textView: UITextView) {
//replace character with * or anyother character
    yourtextView.text = String(repeating: "*", count: (textView.text ?? "").count)
}

别忘了这样做:

yourTextview.delegate = self

我喜欢在聊天类应用程序中使用之前的答案一段时间后分享我自己的实现,其中 UITextView 不断填充和清空。

我的 UITextView 用作不同类型数据(电话、电子邮件等)的文本条目,我不想创建其他 UITextView 专门用于处理此问题场景,所以我决定对其进行子类化并稍微重构代码,因为我遇到了使用外部键盘或以编程方式更改 text 属性 时逻辑中断的情况(执行最后一个 does not call the delegate method).

所以首先子类化...

UITextView 子类

class MyTextView: UITextView {

    var isProtected = false // `true` for activate the password mode
    var plainText: String! = String() // Variable to save the text when `isProtected`

    override var text: String! {
        get { return isProtected ? plainText : super.text }
        set {
            if !isProtected {
                plainText = newValue
            }
            super.text = newValue
        }
    }
}

PS:覆盖text 属性 帮助我们在不调用其他变量的情况下始终获得UITextView 中的纯文本。


然后,在实现委托的视图控制器中...

UITextViewDelegate

extension MyViewController: UITextViewDelegate {

    func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

        if myTextView.isProtected {
            myTextView.plainText = (myTextView.plainText as NSString).replacingCharacters(in: range, with: text) // Basically: when is in password mode, saves all written characters in our auxiliar variable
        }

        return true
    }

    func textViewDidChange(_ textView: UITextView) {
        if myTextView.isProtected {
            textView.text = String(repeating: "•", count: textView.text.count) // Change every letter written with the character "•"
        }
    }

}

最后,您只需要在 MyViewController 中的某处切换 isProtected 标志即可:

myTextView.isProtected = true //or `false`