Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIButton addTarget Selector is not working

SquareBox.swift

class SquareBox {
  func createBoxes() {
    for _ in 0..<xy {
            let button = UIButton()

            button.backgroundColor = .white
            button.setTitleColor(UIColor.black, for: .normal)
            button.layer.borderWidth = 0.5
            button.layer.borderColor = UIColor.black.cgColor
            stack.addArrangedSubview(button)
            button.addTarget(self, action: #selector(click(sender:)) , for: .touchUpInside)
    }
  }

  @objc func click(sender : UIButton) {
    print("Click")
  }
}

ViewController.swift

class GameViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let boxRow = SquareBox() 
        boxRow.createBoxes()
    }
}

Also I've tried @IBAction instead of @objc, it doesn't work, but if I use "click" function in ViewController.swift that I created this object, it's working but I need this function inside of this class.

like image 430
Murat Sahin Avatar asked Jul 18 '17 05:07

Murat Sahin


2 Answers

For those who did not find a solution, here is mine.

If you constructed your UIButton as

let button: UIButton = {
  return UIButton()
}()

Just convert those into

lazy var button: UIButton = {
  return UIButton()
}()

I think this is because of somewhat deallocation as mentioned above.

like image 106
Faruk Avatar answered Sep 19 '22 03:09

Faruk


Now that you have posted relevant information in your question, the problem is quite clear. You have a memory management issue.

In your GameViewController's viewDidLoad you create a local instance of SquareBox. This local instance goes out of scope at the end of viewDidLoad. Since there is no other reference to this instance, it gets deallocated at the end of viewDidLoad.

Since the instance of SquareBox has been deallocated, it is not around to act as the button's target. And your click method is never called.

The solution is to keep a reference in your view controller:

class GameViewController: UIViewController {
    let boxRow = SquareBox() 

    override func viewDidLoad() {
        super.viewDidLoad()
        boxRow.createBoxes()
    }
}
like image 30
rmaddy Avatar answered Sep 19 '22 03:09

rmaddy