Angelus
Angelus

Reputation: 177

Button in UITableViewCell addTarget does not work

In my project I have table view with cells with 3 buttons. When I added target action for them, it did not work.

To avoid bad interaction with other items I created a clean project and tried to addTarget to button in TableViewCell. Even here, it did not work. In this project I set one button to each row.

addTarget method should call presentWebBrowser method. But doesn't. Any ideas?

Here is my code:

import UIKit

class TableViewController: UITableViewController {

let array = ["button1","button2","button3"]

override func viewDidLoad() {
    super.viewDidLoad()
tableView.register(MyCell.self, forCellReuseIdentifier: "cellID")

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source



override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return array.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "cellID", for: indexPath) as! MyCell

    return cell

}

}

class MyCell: UITableViewCell {



var button: UIButton = {
    let button = UIButton(type: UIButtonType.system)
    button.setTitle("Button", for: UIControlState.normal)
     button.addTarget(self, action: #selector(presentWebBrowser), for: .touchUpInside)

    // button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 8)

    return button
}()


override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)

    addSubview(button)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.topAnchor.constraint(equalTo: topAnchor).isActive = true
    button.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
    button.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true



}


required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

@objc func presentWebBrowser(sender: UIButton!) {
    print("tapped")

}



}

Upvotes: 4

Views: 3171

Answers (4)

lefdilia
lefdilia

Reputation: 170

Well, maybe I can help with what worked for me so far:

Create UIButton

lazy var _actionButton: UIButton = {
        let button = UIButton()
        button.setImage(UIImage(named: "reset"), for: .normal)
        button.translatesAutoresizingMaskIntoConstraints = false
        button.addTarget(self, action: #selector(handleAction), for: .touchUpInside)
        return button
    }()

@objc Function

@objc func handleAction(){
    print("test reset via action button...")
}

In tableviewcell class, precisely in init Method, instead of using :

addsubview(_actionButton)

use

contentView.addSubview(_actionButton)

Cheers

Upvotes: 1

TruMan1
TruMan1

Reputation: 36098

Must be in a lazy declaration or after the initializer:

lazy var button: UIButton = {
   let button = UIButton(type: .system)
   button.setTitle("Button", for: UIControlState.normal)
   button.addTarget(self, action: #selector(presentWebBrowser), for: .touchUpInside)
   return button
}()

This is because the target view must finish initialization before a selector can be bound to it.

Upvotes: 4

Masoud Heydari
Masoud Heydari

Reputation: 21

the solution is very simple. add below code in init function:

button.addTarget(self, action: #selector(presentWebBrowser), for: .touchUpInside)

that's it!

Upvotes: 0

Sandeep Bhandari
Sandeep Bhandari

Reputation: 20379

First remove the add target in lazy initialization of button variable

var button: UIButton = {
    let button = UIButton(type: UIButtonType.system)
    button.setTitle("Button", for: UIControlState.normal)
    return button
}()

Modify your code in init as

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    addSubview(button)
    button.addTarget(self, action: #selector(presentWebBrowser), for: .touchUpInside)
    button.translatesAutoresizingMaskIntoConstraints = false
    button.topAnchor.constraint(equalTo: topAnchor).isActive = true
    button.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
    button.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

}

Note use of addTarget on button outside the lazy initialization.

Upvotes: 4

Related Questions