jroyce
jroyce

Reputation: 2148

Update data source of a parent view controller

I have three levels of ViewControllers that drill down from an overall category to a subject within that category to a quote within that subject.

The view controllers are called:

1   CategoryViewController
2   SubjectViewController
3   QuoteViewController

The database table "SUBJECT" has category and subject column.

When I am in the SubjectViewController I can edit or delete subjects and categories.

I want to be able to update the data source of the parent view controller, CategoryViewController and "refresh" its tableView so when I navigate back to it, I already see the changes reflected in the displayed table.

What is the correct way to go about this?

Upvotes: 0

Views: 1084

Answers (3)

murat
murat

Reputation: 4963

I think delegation is the most appropriate method for this task. You should create a new protocol called SubjectViewControllerDelegate and add some methods like:

- (void)subjectViewController:(SubjectViewController*)controller didEditSubject:(Subject*)subject;
- (void)subjectViewController:(SubjectViewController*)controller didDeleteSubject:(Subject*)subject;

SubjectViewController has a delegate property to keep weak reference to its delegate. It calls the delegate methods whenever a data is deleted or edited.

CategoryViewController implements this protocol and sets itself as the delegate of SubjectViewController instance before pushing it to the navigation controller. In this methods you can either refresh the all table, or just update the rows that are changed.

UPDATE:

Assuming that you have only one section in CategoryViewController and keep the subjects in an NSMutableArray, you can use the codes similar to below for updating the relevant part of the table view.

- (void)subjectViewController:(SubjectViewController*)controller didEditSubject:(Subject*)subject{
    NSInteger row;
    NSIndexPath* indexPath;
    NSArray* indexPaths;

    row = [self.subjects indexOfObject:subject];
    indexPath = [NSIndexPath indexPathForRow:row inSection:0];
    indexPaths = [NSArray arrayWithObject:indexPath];
    [self.tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];    
}

- (void)subjectViewController:(SubjectViewController*)controller didDeleteSubject:(Subject*)subject{
    NSInteger row;
    NSIndexPath* indexPath;
    NSArray* indexPaths;

    row = [self.subjects indexOfObject:subject];
    indexPath = [NSIndexPath indexPathForRow:row inSection:0];
    indexPaths = [NSArray arrayWithObject:indexPath];
    [self.subjects removeObjectAtIndex:row];
    [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
}

Upvotes: 1

user187676
user187676

Reputation:

Use the UIViewControllers

@property(nonatomic, readonly) UIViewController *parentViewController

You could do something like that

CategoryViewController *cvc = (id)self.parentViewController
if ([cvc isKindOfClass:[CategoryViewController class]]) {
  // call stuff on cvc, like a table view's -reloadData
}

Or you could introduce a notification type and observe that.

Upvotes: 1

Alex
Alex

Reputation: 5210

You could send a global notification from the active ViewController (for example SubjectViewController) like this:

[[NSNotificationCenter defaultCenter] postNotificationName:@"refresh_data" object:nil];

and then listen for it in the view controllers that you with to refresh like this:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataChanged) name:@refresh_data" object:nil];

- (void)dataChanged {
// perform the refreshing 

}

Upvotes: 0

Related Questions