Search code examples
iosswiftuitextfielddelegate

How to know when the delete button on decimal pad is clicked


I have four textFields and each takes only one character, similar to the lock screen. I can input and move from one textField to next textField.
Problem is when I want to delete and move to previous textField, I don't know when the delete button is clicked.

I'm using:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool

to input and move from one textField to another.

How do I know when the delete key is pressed?


Solution

  • edit/update:

    Xcode 11 • Swift 5.2 or later

    Follow up on this question and Swift 5 syntax can be found on this post


    Original answer

    Swift 1.x

    Following up Istvan answer, you need to post a notification when the deleteBackward is pressed:

    class DigitField: UITextField {
        override func deleteBackward() {
            super.deleteBackward()
            NSNotificationCenter.defaultCenter().postNotificationName("deletePressed", object: nil)
        }
    
    }
    

    Then inside viewDidLoad() you add an observer as follow:

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "goPrevious", name: "deletePressed", object: nil)
    

    and your method:

    func goPrevious() {
        if secondDigit.isFirstResponder() {
            secondDigit.enabled = false
            firstDigit.enabled = true
            firstDigit.becomeFirstResponder()
        } else if thirdDigit.isFirstResponder() {
            thirdDigit.enabled = false
            secondDigit.enabled = true
            secondDigit.becomeFirstResponder()
        } else if fourthDigit.isFirstResponder() {
            fourthDigit.enabled = false
            thirdDigit.enabled = true
            thirdDigit.becomeFirstResponder()
        }
    }
    

    Select your text field and connect it to your DigitField

    enter image description here

    You need to connect each text field to an IBAction (using sent events editing changed)

    enter image description here

    The view controller code should look like this:

    import UIKit
    
    class ViewController: UIViewController {
        
        @IBOutlet weak var firstDigit: UITextField!
        @IBOutlet weak var secondDigit: UITextField!
        @IBOutlet weak var thirdDigit: UITextField!
        @IBOutlet weak var fourthDigit: UITextField!
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            NSNotificationCenter.defaultCenter().addObserver(self, selector: "goPrevious", name: "deletePressed", object: nil)
            
            firstDigit.secureTextEntry = true
            secondDigit.secureTextEntry = true
            thirdDigit.secureTextEntry = true
            fourthDigit.secureTextEntry = true
    
            firstDigit.keyboardType = .DecimalPad
            secondDigit.keyboardType = .DecimalPad
            thirdDigit.keyboardType = .DecimalPad
            fourthDigit.keyboardType = .DecimalPad
    
            firstDigit.becomeFirstResponder()
            secondDigit.enabled = false
            thirdDigit.enabled = false
            fourthDigit.enabled = false
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
        
        func goPrevious() {
            if secondDigit.isFirstResponder() {
                secondDigit.enabled = false
                firstDigit.enabled = true
                firstDigit.becomeFirstResponder()
            } else if thirdDigit.isFirstResponder() {
                thirdDigit.enabled = false
                secondDigit.enabled = true
                secondDigit.becomeFirstResponder()
            } else if fourthDigit.isFirstResponder() {
                fourthDigit.enabled = false
                thirdDigit.enabled = true
                thirdDigit.becomeFirstResponder()
            }
        }
        // You need to connect each text field to an IBAction (using sent events editing changed) – 
        @IBAction func firstChanged(sender: UITextField) {
            if let digitOne = sender.text.toInt() {
                println(digitOne)
                sender.enabled = false
                secondDigit.enabled = true
                secondDigit.becomeFirstResponder()
            } else {
                sender.text = ""
            }
        }
        
        @IBAction func secondChanged(sender: UITextField) {
            if let digitTwo = sender.text.toInt() {
                println(digitTwo)
                sender.enabled = false
                thirdDigit.enabled = true
    
                thirdDigit.becomeFirstResponder()
            } else {
                sender.text = ""
            }
        }
        
        @IBAction func thirdChanged(sender: UITextField) {
            if let digitThree = sender.text.toInt() {
                println(digitThree)
                sender.enabled = false
                fourthDigit.enabled = true
                fourthDigit.becomeFirstResponder()
            } else {
                sender.text = ""
            }
        }
        
        @IBAction func fourthChanged(sender: UITextField) {
            if let digitFour = sender.text.toInt() {
                println(digitFour)
                sender.enabled = false
            } else {
                sender.text = ""
            }
        }
    }