I have an ItemAddViewController, which presents itself as a modal view. One of the fields pushes a new view controller, CategorySelectionViewController, which allows the user to select a single category.
ItemAddViewController.h
@property (nonatomic, retain) Category *category;
CategorySelectionViewController.h
@property (nonatomic, retain) Category *category;
CategorySelectionViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSManagedObject *currentCategory = category;
if (currentCategory != nil) {
NSInteger index = [categories indexOfObject:currentCategory];
NSIndexPath *selectionIndexPath = [NSIndexPath indexPathForRow:index inSection:0];
UITableViewCell *checkedCell = [tableView cellForRowAtIndexPath:selectionIndexPath];
checkedCell.accessoryType = UITableViewCellAccessoryNone;
}
//set the checkmark accessory
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
//update the category
category =[categories objectAtIndex:indexPath.row];
NSLog(@"%@", category);
// Deselect row
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
ItemAddViewController.m
- (void)viewWillAppear:(BOOL)animated {
NSLog(@"%@", category);
}
Category is set on CategorySelectionViewController creation. When category is selected on the category selection screen, NSLog reports the correct object. When it gets back to ItemAddViewController, it's null again. The two should be the same object, so I'm not sure what I'm doing wrong.
Basically, I need a good method to pass data between two view controllers.
@David's is a good answer, but that would keep the data in the
parentViewController
. If you want the data to be local to the ItemAddViewController (the child controller), then you can create a local iVar in the second view and assign a value to it before displaying it or pushing it onto the navigation controller. See my answer to a previous SO question here to see how it is done.To follow up on what's already been said, one approach commonly taken in similar problems is to make the
ItemViewController
(parent) the delegate ofCategorySelectionViewController
(child), and whentableView:didSelectRowAtIndexPath:
fires in theCategorySelectionViewController
, send a message to the delegate callback inItemAddViewController
- passing in the selected category as a parameter.This concept could be implemented similar to the following:
ItemAddViewController's skeleton would then be modified to conform to the
CategorySelectionViewControllerDelegate
protocol:In regard to doing this by calling
[self parentViewController]
inCategorySelectionViewController
, the catch is thatItemAddViewController
inherits fromUITableView
, so when you send the message[self parentViewController]
, the compiler thinks you're talking to aUITableView
, not anItemAddViewController
, unless you cast it explicitly. Therefore, it does not know thatself.parentViewController
has a property calledcategory
. You can fix this by adding the type cast:Hope this helps.
The
parentViewController
method of theUIViewController
class should give you a pointer to the view controller that's "managing" the current one. Once you've got that, you can set thecategory
property on it.That said, I haven't done much with view controllers on iOS yet myself, so I'm not sure what the semantics of "what
parentViewController
should point to for a given view" is... but I'd venture that yourItemAddViewController
instance should probably be the parent for yourCategorySelectionViewController
.Here's an example of how you might do it:
EDIT: The documentation says this for the
parentViewController
method:I'd take this to mean that the
parentViewController
for your modal view's controller points to whatever view controller received the messagepresentModalViewController:animated:
.