How can I change the dots to another character on password field in iOS Swift

后端 未结 3 447
别跟我提以往
别跟我提以往 2021-01-02 17:13

I have a Text Field and I would like to replace the default dot character to something else when the password is hidden. Is there any way to do this easily?

相关标签:
3条回答
  • 2021-01-02 17:48

    Swift 5 ready to use, updated version of crifan answer:

    import UIKit
    
    class PasswordTextField: UITextField, UITextFieldDelegate {
        var realText: String {
            didSet {
                updateMaskStr()
            }
        }
        let maskChar: Character
        
        init(
            frame: CGRect = .zero,
            maskChar: Character = "*"
        ) {
            realText = ""
            self.maskChar = maskChar
            super.init(frame: frame)
            setupActions()
            setupDelegates()
        }
        
        private func setupActions() {
            addTarget(self, action: #selector(textFiledEditingChanged(textField:)), for: .editingChanged)
        }
        
        private func setupDelegates() {
            delegate = self
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        private func updateMaskStr(){
            //change real text to mask char
            var maskStr = ""
            
            for _ in realText {
                maskStr += String(self.maskChar)
            }
            
            text = maskStr
        }
        
        @objc
        private func textFiledEditingChanged(textField: UITextField) { updateMaskStr() }
        
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            let curText = realText
            let updatedStr:String = (curText as NSString).replacingCharacters(in: range, with: string)
            realText = updatedStr
            return false
        }
    }
    
    0 讨论(0)
  • 2021-01-02 17:52

    based on Ron.Kliffer's idea, I have implemented workable full code:

    //
    //  PasswordTextField.swift
    //  CrifanLibSwift
    //
    //  Created by licrifan on 16/7/8.
    //  Copyright © 2016年 licrifan. All rights reserved.
    //
    
    import UIKit
    
    class PasswordTextField: CommonTextField, UITextFieldDelegate {
        var realText:String {
            didSet {
                print("self.text=\(self.text), realText=\(realText)")
    
                updateMaskStr()
            }
        }
        var maskChar:Character
    
        init(frame: CGRect = CGRectZero, maskChar:Character = "*") {
            print("frame=\(frame), maskChar=\(maskChar)")
    
            self.realText = ""
            self.maskChar = maskChar
    
            super.init(frame: frame)
    
            self.secureTextEntry = false
    
            self.addTarget(self, action: #selector(self.textFiledEditingChanged(_:)), forControlEvents: UIControlEvents.EditingChanged)
    
            self.delegate = self
    
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        func updateMaskStr(){
            print("before update: self.text=\(self.text), self.realText=\(self.realText)")
    
            //change real text to mask char
            var maskStr = ""
            for _ in self.realText.characters {
                maskStr += String(self.maskChar)
            }
    
            self.text = maskStr
    
            print("after  update: self.text=\(self.text), self.realText=\(self.realText)")
        }
    
        func textFiledEditingChanged(textField: UITextField) {
            print("textField=\(textField), textField.text=\(textField.text)")
    
            updateMaskStr()
        }
    
        func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
            print("textField=\(textField), range=\(range), string=\(string)")
    
            var allow = true
            let curText = self.realText
            let updatedStr:String = (curText as NSString).stringByReplacingCharactersInRange(range, withString: string)
    
            if updatedStr.characters.count > LoginRegisterPasswordLengthMax {
                print("password exceed max length \(LoginRegisterPasswordLengthMax)")
                allow = false
            }
    
            if allow {
                self.realText = updatedStr
            }
    
            print("curText=\(curText), updatedStr=\(updatedStr), self.realText=\(self.realText)")
    
            return false
        }
    }
    

    and in another view EditInfoView.swift, to use it:

    class EditInfoView: UIView {
    
        var passwordTextField:PasswordTextField
    
        init(editMode:EditInfoMode) {
    
            self.passwordTextField = PasswordTextField()
    
            self.addSubview(self.passwordTextField)
    
            if self.passwordTextField.notHidden {
                //5. password text
                var passwordPlaceholder = "密码(6-20位)"
                if self.editMode == .ChangeLoginPassword {
                    passwordPlaceholder = "旧密码(6-20位)"
                } else if self.editMode == .ForgotPassword {
                    passwordPlaceholder = "输入新密码(6-20位)"
                }
    
                self.passwordTextField.placeholder = passwordPlaceholder
                self.passwordTextField.returnKeyType = UIReturnKeyType.Go
    //            self.passwordTextField.secureTextEntry = true
                constrain(passwordTextField, smsCodeTextField, phoneTextField) {passwordTextField, smsCodeTextField, phoneTextField in
                    passwordTextField.centerX == passwordTextField.superview!.centerX
                    passwordTextField.width == passwordTextField.superview!.width - 2 * LoginRegisterPaddingX
                    passwordTextField.height == CommonTextFieldHeight
    
                    if self.editMode == .ChangeLoginPassword {
                        passwordTextField.top == passwordTextField.superview!.top + EditInfoViewTopPadding
                    } else {
                        passwordTextField.top == smsCodeTextField.bottom + EditInfoViewCommonPaddingY
                    }
                }
            }
    }
    

    finally in a view controller EditInfoViewController.swift to real use it:

    isValid = validatePassword(self, alertPrefix: alertPrefix, passwordStr: self.editInfoView.passwordTextField.realText, doAlertWhenInvalid: doAlertWhenInvalid)
    

    the final effect is:

    0 讨论(0)
  • 2021-01-02 18:09

    2 options here:

    1. Use a normal textfield without the secure input option. When a user enters a character, save it to a string variable, and replace it in the textfield with the character you wish to present instead of the bullets.

    Here's the code (will show the password as $$$$):

    var password: String = ""
    func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool
    {
        password = password+string
        textField.text = textField.text+"$"
        println("\(password)")
        return false
    }
    
    1. check out the answers here: UITextField secureTextEntry bullets with a custom font?
    0 讨论(0)
提交回复
热议问题