Imperialized
Imperialized

Reputation: 443

UITableViewCell Button is not Clickable IOS Swift

So basically I am trying to do this:

I have a TableView that I load a custom cell (xib) into it. This custom cell has its own corresponding custom class to go with it. The cell loads just fine but the button is not clickable (at all, as in you don't even see any type of indication that the button was clicked at all). I did some googling, tried to set the action in the cell, tried using a delegate to handle the action. I am lost.

Here is the code from the files:

ViewController.swift

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        // Use your cell's reuse identifier and cast the result
        // to your custom table cell class.
        let cell = tableView.dequeueReusableCellWithIdentifier("ReserveTableViewCell", forIndexPath: indexPath) as! ReserveTableViewCell

        cell.delegate = self

        let button = cell.locationButton.viewWithTag(1) as? UIButton
        button?.addTarget(self, action: #selector(ReserveTableViewController.loc(_:)), forControlEvents: .TouchUpInside)

        cell.pickupDate.text = "Today"
        cell.returnDate.text = "Tomorrow"

        //cell.locationButton.addTarget(self, action: #selector(loc), forControlEvents: .TouchUpInside)


        return cell
    }

func loc(sender: UIButton!) {
    print("here")
}

CustomCell.swift

import UIKit


protocol ReserveTableViewCellDelegate {
    func pickupLocationClick(cell: ReserveTableViewCell)
}

class ReserveTableViewCell : UITableViewCell {
    @IBOutlet weak var searchButton: UIButton!
    @IBOutlet weak var compactIcon: UIImageView!
    @IBOutlet weak var midsizeIcon: UIImageView!
    @IBOutlet weak var suvIcon: UIImageView!
    @IBOutlet weak var luxuryIcon: UIImageView!
    @IBOutlet weak var sportIcon: UIImageView!
    @IBOutlet weak var pickupIcon: UIImageView!
    @IBOutlet weak var pickupDate: UILabel!
    @IBOutlet weak var returnDate: UILabel!
    @IBOutlet weak var locationButton: UIButton!

    var delegate: ReserveTableViewCellDelegate?

    @IBAction func locationButtonAction(sender: AnyObject) {
        delegate?.pickupLocationClick(self)
    }


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

Some code is still left from other attempts (which is why the protocol method doesn't match the "loc" that is now defined in the viewcontroller.swift file.

In my TableView in storyboard I have selection turned off, when it is on and you tab on the cell it makes it all look "dim" so to speak.

I have the custom class set in my tableview and the outlets/actions are link in IB.

Anyone?

Upvotes: 1

Views: 2691

Answers (3)

Jay
Jay

Reputation: 116

I have set up project just like you did. One thing i noticed in your in ViewController.swift is that you have written following code.

let button = cell.locationButton.viewWithTag(1) as? UIButton //If you will print or debug this button you will see nil
print("Button: \(button)") //prints "Button: nil"
button?.addTarget(self, action: #selector(ReserveTableViewController.loc(_:)), forControlEvents: .TouchUpInside)

Above code is not adding target for your Button. It is adding target for your Buttons subview which has tag value 1. Which is actually nil. Try following code.

cell.locationButton.addTarget(self, action: #selector(ReserveTableViewController.loc(_:)), forControlEvents: .TouchUpInside)(self, action: #selector(clicked), forControlEvents: .TouchUpInside)

Try the following code in your ViewController.swift

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    // Use your cell's reuse identifier and cast the result
    // to your custom table cell class.
    let cell = tableView.dequeueReusableCellWithIdentifier("ReserveTableViewCell", forIndexPath: indexPath) as! ReserveTableViewCell

    cell.delegate = self

    //let button = cell.locationButton.viewWithTag(1) as? UIButton
    //button?.addTarget(self, action: #selector(ReserveTableViewController.loc(_:)), forControlEvents: .TouchUpInside)
    cell.locationButton.addTarget(self, action: #selector(loc), forControlEvents: .TouchUpInside)

    cell.pickupDate.text = "Today"
    cell.returnDate.text = "Tomorrow"


    return cell
}
func loc(sender: UIButton!) {
    print("here")
}

Upvotes: 0

Frankie
Frankie

Reputation: 11918

Couple confusing things here...

let button = cell.locationButton.viewWithTag(1) as? UIButton

This means, hey locationButton, look in your subviews to find viewWithTag of 1. Not what you want. Just use

let button = cell.locationButton

Then you need to decide what action you're calling and what class does it live in. If you want the button to call an action in the ViewController class you add a target like:

button.addTarget(self, action: #selector(ViewController.loc(_:)), forControlEvents: .TouchUpInside)

If you want the button to call an action inside the ReserveTableViewController class, which honestly is pretty odd, you need a way to reference that class

button.addTarget(myReferenceToTheReserveTableViewControllerClass, action: #selector(ReserveTableViewController.loc(_:)), forControlEvents: .TouchUpInside)

What you may be actually looking for is for the button to call a method inside the cell class, in which you can then respond as necessary or delegate out to another class, which would then be:

button.addTarget(cell, action: #selector(ReserveTableViewCell.loc(_:)), forControlEvents: .TouchUpInside)

Upvotes: 0

JFed
JFed

Reputation: 128

In my experience, it is possible to add functionality to the button in both the Cell file and in the ViewController file (which holds your TableView as a member)

ViewController.swift

@IBAction func locationButtonAction(sender: AnyObject) {
    // Do Some Action Here (Which interacts with data members of View
}

CustomCell.swift

@IBAction func locationButtonAction(sender: AnyObject) {
    // Do Another Action (Which interacts with data members of the cell)
}

Both of these functions can be linked to the TouchUpInside of the Cell button using the Storyboard Editor!

Best of luck!

Upvotes: 1

Related Questions