0

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?

jroyce
  • 2,029
  • 2
  • 22
  • 45

3 Answers3

1

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.

1

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];
}
murat
  • 4,893
  • 4
  • 31
  • 29
  • Interesting. I already have a QuotesAppDelegate which I thought was the overall delegate. I need to read up more on delegates as I am not tracking. Should I have a separate delegate for the SubjectViewController or could I use the same one? Could you give me an example of how I would call the delegate and update the changed row. – jroyce Feb 03 '12 at 23:34
  • QuotesAppDelegate is your application delegate and should not be used for this task. You can read more about delegation [here](https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/CommunicateWithObjects.html#//apple_ref/doc/uid/TP40002974-CH7-SW18). I have updated my answer and added some code to show you how to update the changed row of the table view. – murat Feb 04 '12 at 07:49
0

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 

}
Alex Stanciu
  • 5,183
  • 2
  • 24
  • 31