Mike Mclaren
Mike Mclaren

Reputation: 251

InputAccessoryView and my problem (Swift)

I have such screen:

enter image description here

When you click on a textfield, the top of the keyboard should have "two arrows" on the left and the button "Done" on the right.

Like this:

enter image description here


I must say right away that I used Iqkeyboardmanager and because of this library there were problems therefore I had to remove it from the project. So help do it manually.

In the project, I already implemented the Done button, my code:

extension UITextField {

  func addInputAccessoryView(title: String, target: Any, selector: Selector) {
    let toolBar = UIToolbar(frame: CGRect(x: 0.0,
                                          y: 0.0,
                                          width: UIScreen.main.bounds.size.width,
                                          height: 44.0))
    let flexible = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
    let barButton = UIBarButtonItem(title: title, style: .plain, target: target, action: selector)

    toolBar.setItems([flexible, barButton], animated: false)
    self.inputAccessoryView = toolBar
  }
}

final class ProfileSettingsViewController: UIViewController,UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate {

@objc func tapDone() {
    self.view.endEditing(true)
  }

override func viewDidLoad() {
    super.viewDidLoad()
    self.nameTF.addInputAccessoryView(title: "Done", target: self, selector: #selector(tapDone))
    self.companyTF.addInputAccessoryView(title: "Done", target: self, selector: #selector(tapDone))
    self.nameTF.delegate = self
    self.companyTF.delegate = self

..... 

The rest of the code 
      }
}

What i have at the moment:

enter image description here


I need to add two black arrows on the left and make the Done buttons black. Help me please.

If you think my code is bad, you can provide your correct example. I am new in ios development.

Upvotes: 1

Views: 653

Answers (1)

πter
πter

Reputation: 2217

1.Create a custom delegate which will notify the ViewController when some button is pressed inside the Input Accessory View.

protocol MyCustomTextFieldDelegate: class {
    func doneButtonPressed()
    func arrowDownPressed()
    func arrowUpPressed()
}

2.Create a custom subclass of the the UITextField and make a function that will create the Input Accessory View. Define the newly created MyCustomTextFieldDelegate as a weak class property. (Note: we are making this subclass, as we are unable to add the MyCustomTextFieldDelegate as a property to the UITextField directly)

class MyCustomTextField: UITextField {
    weak var customTextFieldDelegate: MyCustomTextFieldDelegate?

    func enableInputAccessoryView() {
        let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
        toolBar.barStyle = UIBarStyle.default
        toolBar.isTranslucent = true
        let space = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action: nil)

        let doneButton = UIBarButtonItem(title: "Done", style: .done, target: self,
                                         action: #selector(textFieldDonePressed))
        doneButton.tintColor = .black

        let arrowDown = UIBarButtonItem(image: UIImage(named: "arrow-right"), style: .done, target: self, action: #selector(arrowUpPressed))
        arrowDown.tintColor = .black

        let arrowUp = UIBarButtonItem(image: UIImage(named: "arrow-right"), style: .done, target: self, action: #selector(arrowDownPressed))
        arrowUp.tintColor = .black

        toolBar.setItems([arrowUp, arrowDown, space, doneButton], animated: false)
        toolBar.isUserInteractionEnabled = true
        toolBar.sizeToFit()

        inputAccessoryView = toolBar
    }

    @objc private func textFieldDonePressed() {
        endEditing(true)
        customTextFieldDelegate?.doneButtonPressed()
    }

    @objc private func arrowDownPressed() {
        customTextFieldDelegate?.arrowDownPressed()
    }

    @objc private func arrowUpPressed() {
        customTextFieldDelegate?.arrowUpPressed()
    }
}

3.In your ViewController change your current UITextField to your new MyCustomTextField and apply the Input Accessory View.

yourTextField.enableInputAccessoryView()

4.Set your ViewController to be the MyCustomTextField delegate.

yourTextField.customTextFieldDelegate = self

5.Confrom your ViewController to the newly created MyCustomTextFieldDelegate, where you will handle the user interaction.

extension YourViewController: MyCustomTextFieldDelegate {
    func doneButtonPressed() {
        // Handle done Pressed
    }
    func arrowDownPressed() {
        // Handle down pressed
    }
    func arrowUpPressed() {
        // Handle up pressed
    }
}

Upvotes: 1

Related Questions