0

I have the following code and the doneButton handler is never invoked. Any idea what might be going wrong?

I have tried many different formats for the selector, also with and without parameters. I also made sure that the UIView received touch events by manually setting userInteractionEnabled = true. Thanks for any help in advance!

*** UPDATE: I have refactored the code completely, but same behaviour:

My Protocol:

import Foundation

protocol CustomDatePickerDelegate {
    func dataPickerDone(date: NSDate)
    func dataPickerChanged(date: NSDate)
}

my class:

import Foundation
import UIKit

class CustomDatePicker{

var delegate: CustomDatePickerDelegate?
var datePicker : UIDatePicker = UIDatePicker()

func CreateDatePicker(sender: UITextField) {

    if (delegate is UIViewController)
    {
        let _self = delegate as! UIViewController

        let _view = UIView(frame: CGRectMake(0, 0, _self.view.frame.width, 220))

        let datePickerView  : UIDatePicker = UIDatePicker(frame: CGRectMake(0, 40, 0, 0))
        datePickerView.datePickerMode = UIDatePickerMode.Date


        let _toolbar = UIToolbar()
        let _doneButton = UIBarButtonItem(title: "DONE", style: UIBarButtonItemStyle.Done, target: self, action: #selector(CustomDatePicker.doneButton))
        _toolbar.translucent = false
        _toolbar.sizeToFit()

        _doneButton.accessibilityLabel = "DoneToolbar"
        let _spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)


        _toolbar.setItems([_spaceButton, _doneButton], animated: false)
        _toolbar.userInteractionEnabled = true
                    datePickerView.addTarget(self, action: #selector(CustomDatePicker.handleDatePicker), forControlEvents: UIControlEvents.ValueChanged)

        _view.addSubview(datePickerView)
        _view.addSubview(_toolbar)

        sender.inputView = _view
    }
}

@objc func handleDatePicker(sender:UIDatePicker) {
    delegate?.dataPickerChanged(datePicker.date)
}

@objc func doneButton(){
    delegate?.dataPickerDone(datePicker.date)
}

}

How I use it from the ViewController:

let _dataPicker : CustomDatePicker = CustomDatePicker()
    _dataPicker.delegate = self
    _dataPicker.CreateDatePicker(dataUI)

func dataPickerDone(date: NSDate) {
    dataUI.text = DataFormatejada(date)
    dataUI.resignFirstResponder()
}

func dataPickerChanged(date: NSDate) {
    dataUI.text = DataFormatejada(date)
}
Batiatto
  • 59
  • 6
  • I think this may be a result of adding the `UIDatePicker` as a subview to the `UITextField`. Also, though not causing the problem, if this is all your class does it really shouldn't be a `UIView` subclass since it seems the method adds the date picker to another view rather than the instance of `MyDatePicker` ever being added to the hierarchy? – George Green Apr 16 '16 at 21:29
  • didn't resolve my problem, thanks anyway! – Batiatto Apr 16 '16 at 21:45
  • Hmm, I assume your date picker is appearing on screen as expected and you can interact with it and change the date? – George Green Apr 16 '16 at 21:50
  • 1
    Also I don't think `button.performSelector(_doneMethod, withObject: nil)` is doing what you expect it to. It is trying to cal the `doneButton` method on the button object, which does not exist since it is an instance method on `MyDatePicker`. – George Green Apr 16 '16 at 21:53
  • yes it shows up , but the valuechanged and the done button are not firing any event – Batiatto Apr 16 '16 at 21:59
  • Where does `CreateDatePicker` get called? – George Green Apr 16 '16 at 22:04

1 Answers1

0

I found a way to resolve the problem after many hours of try-error. The problem is with the target:self reference in the lines:

let _doneButton = UIBarButtonItem(title: "DONE", style: UIBarButtonItemStyle.Done, target: self, action: #selector(CustomDatePicker.doneButton))

and

_toolbar.userInteractionEnabled = true
                    datePickerView.addTarget(self, action: #selector(CustomDatePicker.handleDatePicker), forControlEvents: UIControlEvents.ValueChanged)

so what I have done is to create a new property in MyDatePicker class:

var instance : CustomDatePicker?

change those addTarget methods as:

let _doneButton = UIBarButtonItem(title: "DONE", style: UIBarButtonItemStyle.Done, target: instance, action: #selector(CustomDatePicker.doneButton))
 _toolbar.userInteractionEnabled = true
                    datePickerView.addTarget(instance, action: #selector(CustomDatePicker.handleDatePicker), forControlEvents: UIControlEvents.ValueChanged)

and I use it from the ViewController as:

let _dataPicker : CustomDatePicker = CustomDatePicker()
    _dataPicker.delegate = self   <---- **this made the trick**
    _dataPicker.instance = _dataPicker
    _dataPicker.CreateDatePicker(dataUI)

but this is not elegant and it is a patch for a more fundamental issue. Why self is not providing the instance of the object and I have to manually pass it back when I create the object?

thanks!

Batiatto
  • 59
  • 6