Search code examples
iosswiftuibarbuttonitemuitoolbarrepeat

Add UIToolBar to all keyboards (swift)


I'm trying to add a custom UIToolBar to all of my keyboards with as little repetition. The way I'm currently doing it requires me to add the code to all my viewDidLoads and assign every textfield's delegate to the viewController I'm using. I have tried creating my own UIToolBar subclass but I find that I can't really do that when the target for my "Done" and "cancel" buttons are the self view. Does anyone have any suggestions for creating an easily reusable toolbar? Thanks in advance.

override func viewDidLoad() {
    super.viewDidLoad()

    var toolBar = UIToolbar()
    toolBar.barStyle = UIBarStyle.Default
    toolBar.translucent = true
    toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
    var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: "donePressed")
    var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "cancelPressed")
    var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
    toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
    toolBar.userInteractionEnabled = true
    toolBar.sizeToFit()

    stateField.inputAccessoryView = toolBar
    stateField.delegate = self

Solution

  • Thanks to Glorfindel's suggestion and ncerezo's sample code I solved my problem using extensions.

    extension UIViewController: UITextFieldDelegate{
        func addToolBar(textField: UITextField){
            var toolBar = UIToolbar()
            toolBar.barStyle = UIBarStyle.Default
            toolBar.translucent = true
            toolBar.tintColor = UIColor(red: 76/255, green: 217/255, blue: 100/255, alpha: 1)
            var doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: "donePressed")
            var cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.Plain, target: self, action: "cancelPressed")
            var spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
            toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
            toolBar.userInteractionEnabled = true
            toolBar.sizeToFit()
    
            textField.delegate = self
            textField.inputAccessoryView = toolBar
        }
        func donePressed(){
            view.endEditing(true)
        }
        func cancelPressed(){
            view.endEditing(true) // or do something
        }
    }
    

    Though I still need to call the code below on all of my textfields. I feel like there may be a better way without having to call the function on every textField, but for now this is definitely more reusable.

    override func viewDidLoad() {
        super.viewDidLoad()
        addToolBar(addressField)
    }