I have been battling with passing data between two view controllers for a couple of days now and getting very confused. I'm new to Objective-C and finding some parts tricky to get my head round.
I have a Navigation Controller, FirstView is a form and on this form I have a button which loads SecondView which contains a TableView for the user to select some options. I then want to pass the selection back to the FirstView controller and display the data etc...
I have read alot about this (stackoverflow, iphonedevsdk, CS 193P Resources) and the options i've seen are,
1) ivar in app delegate (dirty and not recommended) 2) create a singleton 3) create a data model class 4) Use protocols and delegates (recommended by apple)
I want to do things right and want to use option 4 - Delegates in my program
Problem is, I don't understand delegates and how to setup and implement them.
Could anyone provide a basic example on how to setup and pass an NSArray using the delegate and 2 view controllers.
Thanks in advance Matt
Delegation is the correct pattern to be used in this case, but your description doesn't look much like delegation as it is using a global variable. Perhaps you're storing global variables in your App Delegate which you should always try to avoid.
Here's a rough outline of what the code should look like:
SecondViewController.h:
@protocol SecondViewControllerDelegate;
@interface SecondViewController;
SecondViewController : UIViewController
{
id<SecondViewControllerDelegate> delegate;
NSArray* someArray;
}
@property (nonatomic, assign) id<SecondViewControllerDelegate> delegate;
@property (nonatomic, retain) NSArray* someArray;
@end
@protocol SecondViewControllerDelegate
- (void)secondViewControllerDidFinish:(SecondViewController*)secondViewController;
@end
SecondViewController.m:
@implementation SecondViewController
@synthesize delegate;
@synthesize someArray;
- (void)dealloc
{
[someArray release];
[super dealloc];
}
- (void)someMethodCalledWhenUserIsDone
{
[delegate secondViewControllerDidFinish:self];
}
FirstViewController.h:
#import SecondViewController
@interface FirstViewController : UIViewController <SecondViewControllerDelegate>
{
...
}
@end
FirstViewController.m:
@implementation FirstViewController
- (void)secondViewControllerDidFinish:(SecondViewController*)secondViewController
{
NSArray* someArray = secondViewController.someArray
// Do something with the array
}
@end
Off top of my head. You can replace _returnedProperty
with your custom object and in setReturnedProperty
method do all the magic before actually assigning the checked value from the table.
@interface FormController : UIViewController {
NSString *_returnedProperty;
}
@property (nonatomic, retain) NSString *returnedProperty;
@end
@implementation FormController
- (void)showChoices {
TableController *tv = [[TableController alloc] initWithDelegate:self];
[self.navigationController pushViewController:tv animated:YES];
[tv release];
}
- (void)setReturnedProperty:(NSString *)string {
NSLog(@"Setting property as a delegate");
[_returnedProperty release];
_returnedProperty = [string retain];
}
@synthesize returnedProperty=_returnedProperty;
@end
@interface TableController : UITableViewController {
id _delegate
}
@end
@implementation TableController
- (id)initWithDelegate:(id)delegate {
self = [super initWithStyle:UITableViewGroupedStyle];
if (!self) return nil;
_delegate = delegate;
return self;
}
- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// do the data retrieval stuff
NSString *returnedProperty = @"foo";
[_delegate setReturnedProperty:returnableProperty];
}
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With