UIButton addTarget does not work inside UITableViewCell class

Viewed 92

Suppose you have a class

class Cell: UITableViewCell
{
    var button: UIButton =
        {
            let obj = UIButton()
            obj.translatesAutoresizingMaskIntoConstraints = false
            obj.addTarget(self, action: #selector(didTapBtn), for: .touchUpInside)
            return obj
        }()
    
    init()
    {
        super.init(style: .default, reuseIdentifier: "identifier")
        //other configurations for UI
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @objc func didTapBtn()
    {
        print("btn tapped")
    }
}

If your table view deque a reusable cell, and you then tap the button it does not work. Here var button has to be a lazy var button in order for it to work. (or you must specify the addTarget when self is created in initializer)

By this I understand that whenever we addTarget to a UIButton, self object has to be initialised at the time of adding target (so it does find self in target).

But when we write the similar code for UIViewController, like

class Controller: UIViewController
{
    var button: UIButton =
        {
            let obj = UIButton()
            obj.translatesAutoresizingMaskIntoConstraints = false
            obj.addTarget(self, action: #selector(didTapBtn), for: .touchUpInside)
            return obj
        }()
    
    init()
    {
        super.init(nibName: nil, bundle: nil)
        //other ui configurations
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @objc func didTapBtn()
    {
        print("btn tapped")
    }
}

Then it is now not necessary for a UIButton to be lazy var, we can keep addTarget as it is in trailing closure of var button, where that closure even runs before initializer and that button target will still work.

What is actually going on behind the scenes, the first way in UITableViewCell class has to be the correct behaviour according to me as self should not be available, before the initialization of the object is done. But how does that addTarget works for a UIViewController class ?

0 Answers
Related