67

I have a list of effects in a table view. I have created a top right bar button which does a push segue to another view controller which helps create a new effect. Now I want to add push segues to the table view cells so that the effects values maybe loaded on the add effects view controller and I can save the edited values.

The question is can I create a push segue programmatically? If not can I pass the effect through a prepareforsegue? If I try to use a prepareforsegue, I run into a problem where control dragging from the UITableView does not let me create a push segue to the add effects view controller.

Shikkediel
  • 5,195
  • 16
  • 45
  • 77
Aviral Bajpai
  • 759
  • 1
  • 6
  • 11
  • Do your navigation stuff in Table view`s delegate method, -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //where index path give you your selected row. } – Vishal Sharma Mar 31 '14 at 10:30

10 Answers10

184

control drag From View Controller to View Controller

From View Controller to View Controlle!

You will need to give an identifier to your segue:

enter image description here

Perform the segue:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"yourSegue" sender:self];
}

Now here is the thing, this will just perform the segue, if you ever needed to pass some data to that view controller. Then you have to implement the following segue delegate:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Make sure your segue name in storyboard is the same as this line
    if ([[segue identifier] isEqualToString:@"yourSegue"])
    {
        //if you need to pass data to the next controller do it here
    }
}
ThomasW
  • 16,981
  • 4
  • 79
  • 106
meda
  • 45,103
  • 14
  • 92
  • 122
  • 4
    Hey @meda, can you tell me which tool you used to create the gif in your post? Thats perfect for describing things! – Alex Cio Jul 25 '14 at 10:38
  • 9
    @亚历山大 sorry for my delay response I used quicktime on mac to record a video then I converted to Gif using this [site](https://imgflip.com/gifgenerator) then I load it on imgur – meda Aug 02 '14 at 15:20
  • 2
    I know this is a really old thread, but for these gif screencasts, [LICECap](http://www.cockos.com/licecap/) is really great – and much quicker. – ryebread May 19 '15 at 16:58
  • I think that OP didnt mention this but whats also important is getting information from the currently selected table view cell. how do we pass the selected row that into the `performSegue` function? – CDM social medias in bio Nov 24 '20 at 02:40
  • 1
    @Maddocks you can use `NSIndexPath` for that – meda Nov 24 '20 at 14:28
55

Swift

This answer shows how to pass data and is updated for Xcode 8 and Swift 3.

Here is how to set up the project.

  • Create a project with a TableView. See here for a simple example.
  • Add a second ViewController.
  • Control drag from the first view controller with the table view to the second view controller. Choose "Show" as the segue type.

enter image description here

  • Click the segue in the storyboard and then in the Attribute Inspector name the Identifier "yourSegue". (You can call it whatever you want but you also need to use the same name in the code.)

enter image description here

  • (Optional) You can embed the everything in a Navigation Controller by selecting the first view controller in the storyboard and the going to Editor > Embed In > Navigation Controller.

Code

First View Controller with TableView:

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    // ...
           
    
    // method to run when table view cell is tapped
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        // Segue to the second view controller
        self.performSegue(withIdentifier: "yourSegue", sender: self)
    }
    
    // This function is called before the segue
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        // get a reference to the second view controller
        let secondViewController = segue.destination as! SecondViewController
        
        // set a variable in the second view controller with the data to pass
        secondViewController.receivedData = "hello"
    }
}

Second View Controller

class SecondViewController: UIViewController {
    
    @IBOutlet weak var label: UILabel!
    
    // This variable will hold the data being passed from the First View Controller
    var receivedData = ""
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        print(receivedData)
    }
}

For a more basic example about passing data between View Controllers see this answer.

Community
  • 1
  • 1
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
52

Here is another option, that doesn't require the use of didSelectRowAtIndexPath.

You just wire up the segue in Interface Builder from the prototype cell to the destination.

From there you can simply:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "AffiliationDetail", let destination = segue.destinationViewController as? AffiliateDetailViewController {
        if let cell = sender as? UITableViewCell, let indexPath = tableView.indexPathForCell(cell) {
            var affiliation = affiliations[indexPath.row]
            destination.affiliation = affiliation
        }
    }
}
skwashua
  • 1,627
  • 17
  • 14
13
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self performSegueWithIdentifier:@"YourPushSegueName" sender:self];
}
Mayank Jain
  • 5,663
  • 7
  • 32
  • 65
6
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyViewController *myVController = (MyViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"StoryBordIdentifier"];
    [self.navigationController pushViewController:myVController animated:YES];
}
Vineesh TP
  • 7,755
  • 12
  • 66
  • 130
3

You have 2 options: ctrl+drag from the prototype cell to the new vc and then you'll segue from each cell and you have to implement prepare for segue.

Second option, in didselectrowatindexpath you can instantiate your new viewcontroller using self.storyboard instantiateviewcontrollerwithidentifier..., then call pushviewcontroller or presentviewcontroller, you don't need segues in storyboard or prepare for segue in this scenario.

Calin Chitu
  • 1,099
  • 7
  • 13
2

You can use this method :

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

You can perform a function on selection of a particular tableview cell in this.

PunjabiCoder
  • 525
  • 2
  • 8
0

You can do this by following methods:

Firstly you need to import another view controller in current view.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {}

inside above method you have to call a method - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated; like this:

yourViewController = [[YourViewController alloc] initWithNibName:@"YourViewController" bundle:nil];
[self.navigationController YourViewController animated:YES];

By this you can achieve push segue when UITableViewCell is selected..

Hope this may help you…!

Bhanu
  • 1,249
  • 10
  • 17
0

Swift 3

After following up Ahmed Daou's answer -> manually drag segue from vc to vc at storyboard

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    self.performSegue(withIdentifier: "SegueIdentifier", sender: nil)    
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "SegueIdentifier" {
        //do something you want
    }
}
yonlau
  • 113
  • 2
  • 8
0
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {

    [self performSegueWithIdentifier:@"segueIdentifier" sender:indexPath];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"segueIdentifier"]) {
        NSIndexPath *indexPath = (NSIndexPath *)sender;

    }
}
Jarvan
  • 31
  • 3