Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 4 UITextField max length in Alert

how can I set max length of UITextField in Alert?

What is the latest best practice for this in Swift 4?

This is my code example, but it will crash because UITextField doesn't exist at beginning.

class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var textField: UITextField!
let limitLength = 10
@IBOutlet weak var player1: UIButton!


func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let text = textField.text else { return true }
    let newLength = text.characters.count + string.characters.count - range.length
    return newLength <= limitLength
}

@IBAction func player1Action(_ sender: UIButton) {
    let alertController = UIAlertController(title: "Please enter you name", message: "Maximum 10 characters", preferredStyle: .alert)
    alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: {
        alert -> Void in
        let textField = alertController.textFields![0] as UITextField
        // do something with textField
        self.player1.setTitle("\(textField.text!)", for: .normal)
    }))
    alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

    alertController.addTextField(configurationHandler: {(textField : UITextField!) -> Void in
        textField.placeholder = "Name"
    })
    self.present(alertController, animated: true, completion: nil)

}


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    textField.delegate = self

}

Many thanks for your time.

like image 1000
Patricia Avatar asked Dec 23 '22 14:12

Patricia


2 Answers

You actually don't need to create an instance of the UITextField. The addTextField closure will return the UITextField for you. All you need to do is set the delegate of that text field in the closure.

class ViewController: UIViewController, UITextFieldDelegate {
    let limitLength = 10
    @IBOutlet weak var player1: UIButton!

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let text = textField.text else { return true }
        let newLength = text.characters.count + string.characters.count - range.length
        return newLength <= limitLength
    }

    @IBAction func player1Action(_ sender: UIButton) {
        let alertController = UIAlertController(title: "Please enter you name", message: "Maximum 10 characters", preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "OK", style: .default, handler: {
            alert -> Void in
            let textField = alertController.textFields![0] as UITextField
            self.player1.setTitle("\(textField.text!)", for: .normal)
        }))
        alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

        alertController.addTextField(configurationHandler: {(textField : UITextField!) -> Void in
            textField.placeholder = "Name"
            textField.delegate = self // Set the delegate
        })

        present(alertController, animated: true, completion: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }
}
like image 192
Chris Avatar answered Jan 02 '23 05:01

Chris


class MaxLengthTextField: UITextField, UITextFieldDelegate {

    private var characterLimit: Int?

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        delegate = self
    }

    @IBInspectable var maxLength: Int {
        get {
            guard let length = characterLimit else {
                return Int.max
            }
            return length
        }
        set {
            characterLimit = newValue
        }
    }

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

        guard string.characters.count > 0 else {
            return true
        }

        let currentText = textField.text ?? ""
        let prospectiveText = (currentText as NSString).replacingCharacters(in: range, with: string)

        // 1. Here's the first change...
        return allowedIntoTextField(text: prospectiveText)
    }

    // 2. ...and here's the second!
    func allowedIntoTextField(text: String) -> Bool {
        return text.characters.count <= maxLength
    }
}

You can use this class for more than one text field. Just add class MaxLengthTextField to any text field. Then you can modify a number of characters in text field from Storyboard. P.s. this is swift 3.0

like image 37
tBug Avatar answered Jan 02 '23 05:01

tBug