Sarthak Kapoor
Sarthak Kapoor

Reputation: 27

Swift prepare for Segue: How to know If a button or a table row initiated Segue

This is my code. I'm trying to perform a segue. I have a bar button item as well as a table with rows performing the same segue. I want to know when the button is clicked and when a particular row.

The following code works for a button but not for the rows of the table

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    activePlaceRow = indexPath.row

    performSegue(withIdentifier: "toMap", sender: nil)

}


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "toMap"
    {
        let mapViewController = segue.destination as! ViewController

        if let senderObject = sender
        {
            if (senderObject as! UIBarButtonItem).tag == 1
            {

                mapViewController.activePlaceRow = -2
            }
            else
            {
                mapViewController.activePlaceRow = activePlaceRow
            }
        }

    }
}

Upvotes: 2

Views: 1306

Answers (3)

bjtitus
bjtitus

Reputation: 4270

One easy thing to do is to check indexPathForSelectedRow or indexPathsForSelectedRows.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

if segue.identifier == "toMap"
{
    let mapViewController = segue.destination as! ViewController

    if let senderObject = sender
    {
        if (senderObject as! UIBarButtonItem).tag == 1
        {

            mapViewController.activePlaceRow = -2
        }
        else
        {
            mapViewController.activePlaceRow = tableView.indexPathForSelectedRow
        }
    }

}

No need for the activePlaceRow this way. You can also create a segue in the storyboard by right clicking on the cell and dragging to the view controller, and then delete your didSelectRow implementation.

Upvotes: 0

vadian
vadian

Reputation: 285082

Just pass the index path as sender

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    performSegue(withIdentifier: "toMap", sender: indexPath)

}


override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "toMap"
    {
        let mapViewController = segue.destination as! ViewController

        if let buttonItem = sender as? UIBarButtonItem, buttomItem.tag == 1 {
            mapViewController.activePlaceRow = -2
        }
        else if let indexPath = sender as? IndexPath {
            mapViewController.activePlaceRow = indexPath.row
        }
    }
}

Upvotes: 3

Brandon A
Brandon A

Reputation: 8279

What you can do is add a property to your UIViewController

var isSegueFromCell:Bool = false

In your didSelectRowAt method you can assign this value as true. Then, when your prepareForSegue method gets called, you check:

if isSegueFromCell {

    print("SEGUE FROM TABLE VIEW")
}
else {
    print("SEGUE FROM BUTTON")
}

OR

When you call performSegue you can pass in a Bool indicating true if being called from your didSelectRow method

performSegue(withIdentifier: "YourSegueID", sender: true)

Then detect this in your prepareForSegue method

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let value = sender as? Bool {
        if value {
            print("FROM TABLE VIEW ROW")
        } else {
            print("FROM BUTTON")
        }
    }
}

Upvotes: 0

Related Questions