-1

I'm studying developing for iOS and while building a simple app which loads data from database and shows it as a tableview, I've got some issues which I fail to understand so far. The master - detail controllers' classes were created by me, not by the XCode template, if this matters.

  1. I try to pass data from master tableview controller to detail controller. The data is as simple as a couple of strings. I use segue for this purpose. In prepareForSegue method I do the following:

    if ([segue.identifier isEqualToString: @"DetailsSegue"]) {
        DetailsViewController* dvc = (DetailsViewController*)segue.destinationViewController;
        NSInteger selectedRow =[self.tableView indexPathForSelectedRow].row;
        dvc.nameLabel.text = [NSString stringWithFormat:@"%@",
                         [[self.entitiesArray objectAtIndex:selectedRow name]];
        ...
    }
    

    The problem here is that dvc.nameLabel is nil. And I guess, that is possibly because the controller has not been fully created yet. Well, the dvc pointer is not nil, but I don't see the log in my init method, so my idea that it was not initialized.

    I decided to create an instance variable of DetailsViewController and in prepareForSegue set it:

    dvc->name = [NSString stringWithFormat:@"%@",
                 [[self.entitiesArray objectAtIndex: selectedRow] name]];
    

    and then I set nameLabel property in viewDidLoad method

    And it actually worked! So I guess I wouldn't be able to set instance variable of an unitialized instance. But I did. So what was wrong? And I feel this is not the way people do it, as to have one more variable that holds the same thing seems redundant.

So what is the proper way of passing a variable (in my case NSString) using a segue to another controller?

Thank you guys for help

rightaway717
  • 2,631
  • 3
  • 29
  • 43
  • possible duplicate of [Passing Data between View Controllers](http://stackoverflow.com/questions/5210535/passing-data-between-view-controllers) – Hot Licks Nov 03 '14 at 16:49

2 Answers2

1

The problem in your code is that you're trying to manipulate the other VCs views. Don't do that. Instead, you should create properties in the destination view controller to hold the data you want to display.

As the other poster said, it makes sense to create a class that contains the data for a record, and pass that. You might have your master view controller's model be an array of these objects. The master would use the data objects to populate a table view. When the user clicked on a row to open a detail view, you'd pass a copy of that data object to the detail view controller in prepareForSegue.

The detail view controller could then edit it if desired, and pass the edited object back to the master view controller if the user saved changes, or simply discard the edited object if the user cancels.

Yes, you could use a singleton to save your data model.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
0

If you want to pass data, you're doing it reasonably. UI elements are not guaranteed to be initialized until the main view of the view controller has finished loading, so a non-UI variable is fairly common.

For a more complex app or one that you expect to grow and maintain, the better approach would be to create a class (or classes) that make up the application's data model. Anything that modifies shared data sends updates to the model and anything that needs to use shared data reads from the model. Among many positive results from that strategy, one is less crosstalk between view controller.

Phillip Mills
  • 30,888
  • 4
  • 42
  • 57
  • Is model class in this approach supposed to be a singleton? – rightaway717 Nov 03 '14 at 14:29
  • It can be a singleton or it can be an object that you can get from the app delegate, somewhat like the app window and root view controller for the view and controller hierarchies. – Phillip Mills Nov 03 '14 at 14:54