Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performing a segue from a button within a custom UITableViewCell

I want to perform a segue from a button within a custom UITableViewCell, but I don't know how to access the cell's contents when I push that button. I realize that this could be accomplished through didSelectRowAtIndexPath, however I have that method performing another function, and I would like to use the button I have created within the table cell.

Here is my perform segue method I'm having trouble with:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
    if segue.identifier == "showComments"
    {
        let vc:CommentOnPostViewController = segue.destinationViewController as CommentOnPostViewController

        var buttonPosition:CGPoint = sender?.convertPoint(CGPointZero, toView: self.feed) as CGPoint!
        var path:NSIndexPath = self.feed.indexPathForRowAtPoint(buttonPosition) as NSIndexPath!

        var postToCommentOn:PFObject = feedList[path.row] as PFObject
        vc.post = postToCommentOn as PFObject
    }
}

I tag the button in the cell when displaying it, and give it a target action:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
    // There is code that goes here for creating and displaying the cell.

    cell.commentButton.tag = indexPath.row
    cell.commentButton.addTarget(self, action: "addComment", forControlEvents: UIControlEvents.TouchUpInside)
}

Here is the action that is called when pressing the button:

func addComment()
{
    self.performSegueWithIdentifier("showComments", sender: self)
}

Any help is appreciated. Thanks!

like image 668
user3353890 Avatar asked Nov 12 '14 06:11

user3353890


People also ask

How do you perform a segue in a Tableview cell?

So, select the first view controller, and then go to the top menu and click on Editor → Embed In → Navigation Controller. For this, we are going to select the “show” segue in the “Selection Segue” section. This means that when you tap on the cell, it will cause this segue to happen.


3 Answers

Create a Protocol with the Method, that will be called by the CustomCell's Delegate, defined on your TableViewController

//Pass any objects, params you need to use on the 
//segue call to send to the next controller.

protocol MyCustomCellDelegator {
    func callSegueFromCell(myData dataobject: AnyObject)
}

Now use the Protocol on your UITableViewController

class MyTableViewController : UITableViewController, MyCustomCellDelegator {


 //The usual Defined methods by UIViewController and UITableViewController 

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

  //Set the CustomCell new Delegate
  var cell = tableView.dequeueReusableCellWithIdentifier(customIdentifier) as MyCustomCell


  cell.delagete = self

  return cell

 }


 //MARK: - MyCustomCellDelegator Methods

 func callSegueFromCell(myData dataobject: AnyObject) {
   //try not to send self, just to avoid retain cycles(depends on how you handle the code on the next controller)
   self.performSegueWithIdentifier("showComments", sender:dataobject )

 }

}

Define the Delegate on your Custom Cell and the Call inside your New Button the Delegate Function.

class MyCustomCell : UITableViewCell {

      var delegate:MyCustomCellDelegator!
      @IBOutlet weak var myButton:UIButton



     @IBAction func buttonPressed(sender:AnyObject){
           var mydata = "Anydata you want to send to the next controller"
           if(self.delegate != nil){ //Just to be safe.
             self.delegate.callSegueFromCell(mydata)
           }
    }
}

Hopefully this can be clean and clear for you to understand and implement in your code.

like image 102
S.H. Avatar answered Nov 03 '22 02:11

S.H.


I found an swiftier answer for passing data with a button in a dynamic cell to a new VC.

  1. Setting up a Tableview, a custom cell (connect the cell with your created class and set a cell-identifier) and create a new VC and connect it via a segue (also set an identifier for the segue) to your current TableViewController

  2. setting up your cell with the outlet (cellButton)

    class CustomCell: UITableViewCell {
        @IBOutlet weak var cellButton: UIButton!
    
    
       override func awakeFromNib() {
           super.awakeFromNib()
       }
    
       override func setSelected(_ selected: Bool, animated: Bool) {
          super.setSelected(selected, animated: animated)
       }
    }
    
  3. CellForRowAt function in the TableViewController-Class

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
        let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as! CustomCell
    
        //...Do stuff for your cell
    
        cell.cellButton.tag = indexPath.row //or value whatever you want (must be Int)
        cell.cellButton.addTarget(self, action: #selector(TableViewController.buttonTapped(_:)), for: UIControlEvents.touchUpInside)
     }
    
  4. set up the button method that's called by the target of the button

    func buttonTapped(_ sender:UIButton!){
        self.performSegue(withIdentifier: "customSegueIdentifier", sender: sender)
    }
    
  5. prepare for segue function

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if(segue.identifier == "customSegueIdentifier") {
            if let destination = segue.destination as? YourNewViewController {
    
               if let button:UIButton = sender as! UIButton? {
                   print(button.tag) //optional
                   destination.valueViaSegue = button.tag
               }
            }
        }
    }
    

Hope this code will help you guys. keep coding ;)

like image 41
Marco Weber Avatar answered Nov 03 '22 02:11

Marco Weber


Here's what I did

In your UITableViewCell class, added the following

protocol MyCustomCellDelegator {

    func callSegueFromCell(myData dataobject: AnyObject)

}
class MyUITableViewCell: UITableViewCell {

    var delegate:MyCustomCellDelegator!

    .......


    @IBAction func buttonPress (_ sender: Any){


        if(self.delegate != nil){

            self.delegate.callSegueFromCell(myData: )

        }

    }

}

And in the UITableViewController

class STVHomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, MyCustomCellDelegator {


    .....

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


        if let cell = tableView.dequeueReusableCell(withIdentifier: "MyIdentifier") as? MyIdentifierCell {

            // configure your cell
            cell.configureCell(myIdentifier:)

            // This line is important 
            cell.delegate = self

            return cell

        } else {

            return MyIdentifierCell()
        }

    }

    func callSegueFromCell(myData dataobject: AnyObject) {

        print(dataobject)
        self.performSegue(withIdentifier: "goToNextVC", sender: dataobject )


    }

}
like image 43
Arjun Avatar answered Nov 03 '22 02:11

Arjun