Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Issue in `becomeFirstResponder()` in swift

I have six textfields. Now if all my textfield are filled and tap on any textfield the it should always put focus on sixth textfield & show the keyboard. I have tried below code but it does not show keyboard and only put focus when I tap on sixth textfield. please tell me what is the issue with this ?

func textFieldDidBeginEditing(_ textField: UITextField) {
     textField.inputAccessoryView = emptyView
        if let textOneLength = textFieldOne.text?.length ,let textTwoLength = textFieldTwo.text?.length ,let textThreeLength = textFieldThree.text?.length , let textFourLength = textFieldFour.text?.length,let textFiveLength = textFieldFive.text?.length , let textSixLength = textFieldSix.text?.length {
            if (textOneLength > 0) && (textTwoLength > 0) && (textThreeLength > 0) && (textFourLength > 0) && (textFiveLength > 0) && (textSixLength > 0) {
                self.textFieldSix.becomeFirstResponder()
            } else if (textOneLength <= 0) && (textTwoLength <= 0) && (textThreeLength <= 0) && (textFourLength <= 0) && (textFiveLength <= 0) && (textSixLength <= 0){
                self.textFieldOne.becomeFirstResponder()
            }
        }
}
like image 409
TechChain Avatar asked Mar 22 '18 12:03

TechChain


1 Answers

I think accepted answer is hack. Other thing that we can do is detect touchDown on UITextField, check if last textField should be in focus and do becomeFirstResponder() on it. Next thing, we should disallow focus other textFields if last should be in focus. We can do that in textFieldShouldBeginEditing method.

Here example of ViewController. Just connect 3 textFields and all should work as expected (Swift 4):

class ViewController: UIViewController {

    @IBOutlet weak var firstTextField: UITextField!
    @IBOutlet weak var secondTextField: UITextField!
    @IBOutlet weak var thirdTextField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        firstTextField.delegate = self
        secondTextField.delegate = self
        thirdTextField.delegate = self

        firstTextField.addTarget(self, action: #selector(textFieldTouch(_:)), for: .touchDown)
        secondTextField.addTarget(self, action: #selector(textFieldTouch(_:)), for: .touchDown)
        thirdTextField.addTarget(self, action: #selector(textFieldTouch(_:)), for: .touchDown)
    }

    @IBAction private func textFieldTouch(_ sender: UITextField) {
        if shouldFocusOnLastTextField {
            thirdTextField.becomeFirstResponder()
        }
    }

    private var shouldFocusOnLastTextField: Bool {
        return firstTextField.text?.isEmpty == false && secondTextField.text?.isEmpty == false  && thirdTextField.text?.isEmpty == false
    }

}

extension ViewController: UITextFieldDelegate {

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        guard shouldFocusOnLastTextField else { return true }
        return textField == thirdTextField
    }

}

Other, more simple way to achieve that check the textField that is going to be focused:

extension ViewController: UITextFieldDelegate {

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        guard firstTextField.text?.isEmpty == false &&
            secondTextField.text?.isEmpty == false  &&
            thirdTextField.text?.isEmpty == false &&
            textField != thirdTextField else { return true }

        thirdTextField.becomeFirstResponder()
        return false
    }

}
like image 122
pacification Avatar answered Sep 22 '22 01:09

pacification