Osama Naeem
Osama Naeem

Reputation: 1954

UIButton selector is not working

I have a view that is placed as a subview of navigationController in order to fill the whole display. On this view I have a subview that has two buttons. "Remove and Done". and then it also has a datepicker. The datePicker works, however, the Remove and Done buttons are not firing the action functions.

The buttons:

 var setButton: UIButton = {
   var button = UIButton(type: .system)
    button.setTitle("Done", for: .normal)

    button.tintColor = .white
    button.addTarget(self, action: #selector(handleReminderSetBtn), for: .touchUpInside)

    return button
}()

var cancelButton: UIButton = {
    var button = UIButton(type: .system)
    button.setTitle("Remove", for: .normal)
    button.tintColor = .white
    button.addTarget(self, action: #selector(handleReminderCancelBtn), for: .touchUpInside)

    return button
}()

The main blackView that is in the navigationController:

   viewOverLay.addSubview(cardreminder1)

   viewOverLay.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height)

   viewOverLay.backgroundColor = UIColor.black.withAlphaComponent(0.3)
   self.navigationController?.view.addSubview(viewOverLay)

CardReminder1 is the UIView on which I have two buttons.

enter image description here

I reckon there is some issue with the target in the addTarget method of the two buttons. What could be the issue?

Upvotes: 5

Views: 2122

Answers (2)

Charlie Fish
Charlie Fish

Reputation: 20546

I just had a similar issue. Along with the other answer posted, making the property lazy worked in my case as well. It depends on when you first try to access that property, but in my case I only accessed it after initialization was complete, so making the property lazy worked perfectly.

For example in your case, the following might work:

lazy var setButton: UIButton = {
    var button = UIButton(type: .system)
    button.setTitle("Done", for: .normal)

    button.tintColor = .white
    button.addTarget(self, action: #selector(handleReminderSetBtn), for: .touchUpInside)

    return button
}()

lazy var cancelButton: UIButton = {
    var button = UIButton(type: .system)
    button.setTitle("Remove", for: .normal)
    button.tintColor = .white
    button.addTarget(self, action: #selector(handleReminderCancelBtn), for: .touchUpInside)

    return button
}()

Upvotes: 1

mugx
mugx

Reputation: 10105

You shouldn't initialize setButton and cancelButton in that way.

Quoting the Apple documentation from Setting a Default Property Value with a Closure or Function:

If you use a closure to initialize a property, remember that the rest of the instance has not yet been initialized at the point that the closure is executed. This means that you cannot access any other property values from within your closure, even if those properties have default values. moreover:

You also cannot use the implicit self property, or call any of the instance’s methods, hence the problem is here:

addTarget(self...)

so to fix the issue you should move the buttons initialization (or move the addTarget) after your CardReminder1 is fully initialized.

Upvotes: 2

Related Questions