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

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?

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:

enter image description here