简体   繁体   中英

next view controller is not loaded when the segue is performed

I am still new to the storyboard stuff. I spent two days debugging this problem. It seems the destination view controller of a segue is not working properly when the -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender is called.

I have a table view and when a cell is tapped, it calls for a segue

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    VAItem *item = [category itemAtIndex:indexPath.row];
    [self performSegueWithIdentifier:@"SegueShowDetail" sender:item];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"SegueShowDetail"]) {

        VADetailViewController *detailViewController = segue.destinationViewController;
        detailViewController.item = (VAItem*) sender; // <-- THIS ASSIGNMENT DOES NOT WORK       
    }
}

My debugging shows, the item is correctly passed down to prepareForSegue but the detailViewController.item is a wild pointer. It's not initialized and the = assignment does not have any effect.

I put a breakpoint in VADetailViewController's viewDidLoad and found out that the item variable is still the wild pointer address even though the assignment has taken place.

@interface VADetailViewController : UIViewController
// data
@property (nonatomic, retain) VAItem *item;
@end

item is also correctly synthesized.

Any help is much appreciated

Leo

If you're using a storyboard segue to transition to the next viewcontroller you don't need to use tableVeiew:didSelectRowAtIndexPath: in this situation. Depending how you have things set up that could be contributing to the problem.

In your storyboard, make sure you have drawn your push segue from your tableview's Prototype Cell to the detail view controller (ie from the cell, NOT from the tableViewController). If you have your storyboard set up that way your segue will be triggered as soon as the user selects a cell. A reference to the cell itself will be passed to prepareForSegue:sender: as the sender parameter. You can then inspect that object to find out which row was clicked in that method.

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"SegueShowDetail"]) {

        // sender will be the tableview cell that was selected
        UITableViewCell *cell = (UITableViewCell*)sender;
        NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

        VAItem *item = [category itemAtIndex:indexPath.row];

        VADetailViewController *detailViewController = segue.destinationViewController;
        detailViewController.item = item;       
    }
}

You really only want to use one of

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

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

to pass your data along to the next view controller. If you want to use the latter in your case, then you need to change your code to something along the lines of:

if ([segue.identifier isEqualToString:@"SegueShowDetail"]) {

    VADetailViewController *detailViewController = segue.destinationViewController;
    detailViewController.item = [catagory itemAtIndex:[self.tableView indexPathForSelectedRow].row];
}

I think you were getting an error because of what you assigned your sender. Here is the reference to the docs that explain what 'sender' should be.

https://developer.apple.com/library/IOs/#documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/performSegueWithIdentifier:sender :

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM