lorenzoid
lorenzoid

Reputation: 1832

Passing objects between UITableViews

I am trying to implement -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

So far this is what I have in my first UITableViewController:

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{    
    secondviewcontroller *vc = [[secondviewcontroller alloc]init];

    BudgetPlan *tempBudget = [self.budgetElements objectAtIndex:indexPath.row];

    vc.budgetPlan = tempBudget;
}

My second view controller has the ff:

// secondviewcontroller.h

@property (strong, nonatomic) BudgetPlan *budgetPlan;


//secondviewcontroller.m

@synthesize budgetPlan = _budgetPlan

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSLog(@"%@ was passed with %@",self.budgetPlan.name, self.budgetPlan.amount);

self.budgetName.text = _budgetPlan.name;
    self.amountBudgeted.text = [NSString stringWithFormat:@"%.02f", _budgetPlan.amount];
}

Unfortunately, the NSLog shows up as nil. Consequently, UILabels budgetName.text and amountBudgeted.text are also empty.

I've set the datasource and delegates to the custom UIViewController which contains the UITableView element (this is not a UITableViewController). It seems like I am passing the object, but it doesn't seem to be passing...

Where am I going wrong?

Upvotes: 0

Views: 144

Answers (3)

lorenzoid
lorenzoid

Reputation: 1832

Thanks all. The problem seems to be my use of storyboards. This

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath method seems to only work when not using storyboards.

I answered it by using Segues instead.

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

/*
 When a row is selected, the segue creates the detail view controller as the destination.
 Set the detail view controller's detail item to the item associated with the selected row.
 */

    if ([[segue identifier] isEqualToString:@"showDetailsOfBudget"]) 
    {
        NSIndexPath *indexPath = [self.budgetsTable indexPathForSelectedRow];
        BudgetDetailsViewController *detailsViewController = [segue destinationViewController];
        detailsViewController.budget = [self.budgetPlan.budgets objectAtIndex:indexPath.row];
    }
}

Upvotes: 0

pjrharley
pjrharley

Reputation: 35

Firstly, try the suggestion above (log out the budgetPlan object itself to see if that is nil).

If it isn't nil, then you'll have to look elsewhere in your code to see why the properties on it are nil.

If it is nil then the problem is your use of viewDidLoad.

You don't know when viewDidLoad will have been called. You've got two options:

1. Don't use viewDidLoad to do that - you could use viewWillAppear instead

2. If second view controller is only ever associated with one budget plan, then don't set the property like that but make a custom init method:

    -(id) initWithBudgetPlan:(BudgetPlan *)plan
    {
       if (self = [super init])
       {
         self.budgetPlan = plan;
       }
       return self;
    }

Upvotes: 1

Max
Max

Reputation: 989

You are creating an budgetPlan object but in your code you never set the properties name and amount.

in viewDidLoad you are actually logging exactly these properties, which are still nil and NSLog logs (null).

NSLog(@"%@ was passed with %@",self.budgetPlan.name, self.budgetPlan.amount);

You could try logging budgetPlan itself. You should get an object memory address.

Upvotes: 1

Related Questions