1

I have a page where there is a UITextField that I add programmatically, I set the text type to number and add constraints and all that. Then I add a done button to the accessoryView of the text field and add a function to run when that done button is pressed. My problem is, when the page loads, I want the text field to be focused and the keyboard shown. I set the becomeFirstResponder on it, but when the page loads, the keyboard shows up for a split second then immediately disappears and the delegate methods are run.

I need to find a way to make the text field "active", "focused", whatever you want to call it when the page loads, and for the keyboard to be there and ready. I can't seem to find any help aside from call becomeFirstResponder on it, which only works for a split second.

Here is the code I am using to build the page and run everything, I simplified it to reduce clutter and read times, but if you need more info, please let me know and I will be happy to provide the full code...

class AgeViewController: UIViewController {

  var selectedAge: Int = 0
  var textInput: UITextField!

  let settings = UserDefaults.standard

  override func viewDidLoad() {
    super.viewDidLoad()
    createPage()
  }

  override func viewWillAppear(_ animated: Bool) {
    textInput.becomeFirstResponder()
    //I have tried this in both viewWillAppear and viewDidAppear
  }

  func createPage() {
    textInput = UITextField()
    textInput.font = .systemFont(ofSize: 50)
    textInput.placeholder = "35"
    textInput.borderStyle = .none
    textInput.keyboardType = .numberPad
    textInput.returnKey = .done
    textInput.textAlignment = .right
    addDoneButton()
    textInput.delegate = self
    view.addSubView(textInput)
    //create a label and add it to the page
  }

  private fun addDoneButton() {
    let doneToolbar: UIToolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50)
    doneToolbar.barStyle = .default
    let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(doneTapped))
    let items = [flexSpace, done]
    doneToolbar.sizeToFit()
    textInput.inputAccessoryView = doneToolbar
  }

  @objc func doneTapped() {
    textInput.resignFirstResponder()
  }

}

extension AgeViewController: UITextFieldDelegate {
  func textFieldDidBeginEditing(_ textField: UITextField) {
    textField.textColor = UIColor(named: "text")!
  }
  func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
    if textField.text != nil {
      selectedAge = Int(textField.text!) ?? 35
      settings.set(selectedAge, forKey: Strings.age)
    } else {
      textField.textColor = UIColor(named: "grayText")!
    }
  }

Like I said, the page loads, the keyboard shows up for a split second, then goes away and the delegate methods are called for didEndEditing. I don't understand why it isn't staying focused, I am calling becomeFirstResponder. I have tried calling textInput.becomeFirstResponder() in 3 different places, all with the same result. The first was right after I add the subview to the view, then I tried in viewDidAppear and finally in viewWillAppear, all have the same result, shows up for a split second, then goes away. Sorry for the long post, thank you for any help, I really appreciate it.

Neglected Sanity
  • 1,770
  • 6
  • 23
  • 46

0 Answers0