3

I have a requirement to show "#" instead of bullets for password field. But as there is no default option available for it in UITextField.

I have tried to write custom logic in "shouldChangeCharactersInRange" But i am not able to handle the index when user will remove or add any specific character from in-between.

So here are my questions :- 1. Do i need to find any library 2. There is any other default option available for it? 3. Need to write custom logic for it? If so where i can handle it correctly "shouldChangeCharactersInRange" or "textFieldDidChange"

P.J
  • 6,547
  • 9
  • 44
  • 74
Awesome.Apple
  • 1,316
  • 1
  • 11
  • 24
  • 2
    Possible duplicate of [change the secure password character in UITextfield](http://stackoverflow.com/questions/3280069/change-the-secure-password-character-in-uitextfield) – eli-bd May 12 '17 at 05:33

3 Answers3

6
  1. No you dont need to find any 3rd party library for this logic
  2. No there is no default option available for your need
  3. Yes, you need to write a custom logic for your demand, So here it goes...

    var passwordText = String()
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    
    if textField == textFieldPassword {
    
        var hashPassword = String()
        let newChar = string.characters.first
        let offsetToUpdate = passwordText.index(passwordText.startIndex, offsetBy: range.location)
    
        if string == "" {
            passwordText.remove(at: offsetToUpdate)
            return true
        }
        else { passwordText.insert(newChar!, at: offsetToUpdate) }
    
        for _ in passwordText.characters {  hashPassword += "#" }
        textField.text = hashPassword
        return false
    }
    

Swift 4:-

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    if textField == textFieldPassword {

        var hashPassword = String()
        let newChar = string.first
        let offsetToUpdate = passwordText.index(passwordText.startIndex, offsetBy: range.location)

        if string == "" {
            passwordText.remove(at: offsetToUpdate)
            return true
        }
        else { passwordText.insert(newChar!, at: offsetToUpdate) }

        for _ in 0..<passwordText.count {  hashPassword += "#" }
        textField.text = hashPassword
        return false
    }
    return true
}
V D Purohit
  • 1,179
  • 1
  • 10
  • 23
Mr. Bean
  • 4,221
  • 1
  • 19
  • 34
  • Thanks. But i am using swift 2.3 so what would be alternative for this function -- let offsetToUpdate = passwordText.index -- It says String has no member index. – Awesome.Apple May 12 '17 at 05:51
  • Bro that was swift 3 syntax, let me search the replacement for you !! – Mr. Bean May 12 '17 at 05:52
  • Hey, checkout this link to insert new char in string : http://stackoverflow.com/questions/31550835/convert-a-string-to-an-array-of-characters-swift-2-0 – Mr. Bean May 12 '17 at 05:54
  • Check [This](http://stackoverflow.com/questions/30403550/how-can-i-change-the-dots-to-another-character-on-password-field-in-ios-swift) and [UITextField secureTextEntry bullets with a custom font?](http://stackoverflow.com/questions/20969451/uitextfield-securetextentry-bullets-with-a-custom-font) – Agent Smith May 12 '17 at 05:55
  • But this line is not inserting a new character? This is just checking index? – Awesome.Apple May 12 '17 at 05:58
  • Yes you need to find the index to append or remove the character. Find the replacement of this line and you are good to go, actually i dont have xCode 7.x. – Mr. Bean May 12 '17 at 06:02
  • Got anything ?? – Mr. Bean May 12 '17 at 06:07
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/144028/discussion-between-awesome-apple-and-mr-bean). – Awesome.Apple May 12 '17 at 06:16
  • @Mr.BeanI am getting this error Thread 1: Fatal error: String index is out of bounds, Any idea? – Anand Gautam May 11 '22 at 11:17
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.

 class ViewController: UIViewController,UITextFieldDelegate {

   let textField = UITextField(frame :CGRect(x:16,y:50,width:200,height: 40))
    override func viewDidLoad() {
               super.viewDidLoad()

             textField.delegate = self
             self.view.addSubview(textField)
               textField.becomeFirstResponder()
}

var password: String = ""
  func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool{

       password = password+string
       textField.text = textField.text!+"#"//Character you want
       print("\(password)")
       return false
  }
}

This is in Swift 2. Hope it Helps!!

Agent Smith
  • 2,873
  • 17
  • 32
0

Improved Mr. Bean's answer in swift 5. To fix Copy&Paste bugs.

var passNSString : NSString = ""
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        
        var hashPassword = String()
        
        passNSString = passNSString.replacingCharacters(in: range, with: string) as NSString
        for _ in 0..<passNSString.length {  hashPassword += "#" }
        textField.text = hashPassword
        print("str", passNSString)
        return false
        
    }
QrrrQ
  • 11
  • 1