7

This question is not duplicated from these:

I have two TextFields.

@IBOutlet weak var textField1: UITextField!
@IBOutlet weak var textField2: UITextField!
  • textField1 has the Next button like the Return Key;

  • textField2 has the Go button like the Return Key;

textField1

textField2

I would like to enable the Go button of the second TextField just if both TextFields are not empty.

I tried to use someTextField.enablesReturnKeyAutomatically with TextFieldDelegate, but did not work.

Thank you for help.

Community
  • 1
  • 1
Calebe Emerick
  • 83
  • 1
  • 1
  • 7
  • How have you set up `textField1`:s next responder to be `textField2?` (The prior having "Next" rather than "Return"). Just `textField1.returnKeyType = UIReturnKeyType.Next`? – dfrib Feb 11 '16 at 22:46
  • Yeah I think this is tricky (example: `textField1` is empty but `textField2` is not: `Go` button will be enabled). I've seen some undocumented obj-c hacks for setting the return button as enabled/disabled, but I haven't been able to adapt them to swift. Also, we'd like to avoid undocumented hacks. See [this thread]. – dfrib Feb 11 '16 at 23:03
  • Ok this is my final try below, I need to go to bed now. This final version disables the second text view as long as the first text view is empty. Thereafter, diables "Go" button i second text view as long as it's empty. – dfrib Feb 11 '16 at 23:17
  • I tried do it, but I figured out that is not good to UX. – Calebe Emerick Feb 12 '16 at 15:20
  • I agree it's a bit ugly. Probably your best solution is to use `enablesReturnKeyAutomatically` to check only for empty input in each `textFieldX` on their own, an include some runtime check that yields a warning (and abort some operation) if `Go` is pressed while `textField1` is empty. – dfrib Feb 12 '16 at 15:58

2 Answers2

8

Below: textField2 is disabled as long as textField1 is empty. If the latter is non-empty, we enable textField2, but enable the Go button only if textField2 is non-empty (via .enablesReturnKeyAutomatically property),

/* ViewController.swift */
import UIKit

class ViewController: UIViewController, UITextFieldDelegate {
    @IBOutlet weak var textField1: UITextField!
    @IBOutlet weak var textField2: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        // text field delegates
        textField1.delegate = self
        textField2.delegate = self

        // set return key styles
        textField1.returnKeyType = UIReturnKeyType.Next
        textField2.returnKeyType = UIReturnKeyType.Go

        // only enable textField2 if textField1 is non-empty
        textField2.enabled = false

        // only enable 'go' key of textField2 if the field itself is non-empty
        textField2.enablesReturnKeyAutomatically = true
    }

    // UITextFieldDelegate
    func textFieldShouldReturn(textField: UITextField) -> Bool {

        if (textField1.text?.isEmpty ?? true) {
            textField2.enabled = false
            textField.resignFirstResponder()
        }
        else if textField == textField1 {
            textField2.enabled = true
            textField2.becomeFirstResponder()
        }
        else {
            textField.resignFirstResponder()
        }

        return true
    }
}

Runs as follows:

enter image description here

dfrib
  • 70,367
  • 12
  • 127
  • 192
  • 4
    Is there a way to do this based on length of the input? i.e. we need more than 10 characters before you can hit next. – Zorayr May 29 '20 at 22:16
1
class ViewController: UIViewController, UITextFieldDelegate {
    
    @IBOutlet weak var textField1: UITextField!
    @IBOutlet weak var textField2: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        textField1.delegate = self
        textField2.delegate = self
    }
    
    func textFieldDidBeginEditing(_ textField: UITextField) {
        if textField === textField2 {
            setReturnKeyState(for: textField, isEnabled: shoulEnableReturnKey(), delay: 0.1) // A bit hacky it needs delay here
        }
    }
    
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if textField === textField2 {
            if var text = textField.text, let range = Range(range, in: text) {
                text.replaceSubrange(range, with: string)
                setReturnKeyState(for: textField, isEnabled: shoulEnableReturnKey())
            }
        }
        return true
    }
    
    private func shoulEnableReturnKey() -> Bool {
        textField1.hasText && textField2.hasText
    }
}
   
extension UITextFieldDelegate {
    func setReturnKeyState(for textField: UITextField, isEnabled: Bool, delay: Double? = nil) {
        textField.enablesReturnKeyAutomatically = false
        if textField.delegate != nil {
            if let delay = delay {
                DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
                    textField.setValue(isEnabled, forKeyPath: "inputDelegate.returnKeyEnabled")
                }
            } else {
                textField.setValue(isEnabled, forKeyPath: "inputDelegate.returnKeyEnabled")
            }
        }
    }
}
Paul B
  • 3,989
  • 33
  • 46