Alfawan Alfawan - 10 months ago 62
iOS Question

UIButtonBarItem does not seem to fire selector

I am writing a simple iOS app in XCode 7.3, which I believe puts me using Swift 2.2. I am trying to use a UIDatePicker with UIToolbar with a UITextfield, and for some reason I tapping on the Cancel button seems not to call the method datePickerCancelled on the controller. Everything displays fine(picker, buttons , etc.), but the event won't fire. I have tried several variations of adding the selector to the UIBarButtonItem, and nothing seems to work. As you can see from the code this a pretty trivial case so it escapes why it should be this difficult. Thank you.

override func viewDidLoad() {

var datePicker = UIDatePicker()
var datePickerToolbar = UIToolbar()
let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Done, target: nil, action: nil)
let cancelButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Cancel, target: self, action: #selector(datePickerCancelled))
let flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)

datePickerToolbar.setItems([cancelButton,flexSpace, doneButton], animated: true)
datePicker.userInteractionEnabled = true
cancelButton.enabled = true
self.dateField.inputView = datePicker
self.dateField.inputAccessoryView = datePickerToolbar

func datePickerCancelled(){

}` I

Answer Source

The problem is this line:

var datePickerToolbar = UIToolbar()

This results in a toolbar of zero size. The Cancel button is visible, but it is outside of its superview, namely the toolbar — because the toolbar has zero size.

A view outside of its superview cannot be tapped.

You can easily confirm this by setting the toolbar's clipsToBounds to true and running the app. The Cancel button will now be invisible, because things outside the toolbar are no longer shown.

If the event did fire, your datePickerCancelled function still wouldn't do anything:

func datePickerCancelled(){

Your date picker was never first responder, so that line wouldn't cause anything to happen.

Perhaps you meant this:

func datePickerCancelled(){