So passing data forward from your first viewcontroller to the second view controller is pretty easy as the first viewcontroller has direct access to the second viewcontroller and it can just set the properties. But the other way around is not that simple and needs a little bit of an extra coding. To pass data between the viewcontrollers you have to define a protocol that will implement at least one method that we can use. The first viewcontroller then becomes a delegate for the second viewcontroller and must adhere to the protocol's required methods. Basically the delegate function becomes the callback method when the response comes back from the second view controller.
Here is an example where we create two viewcontrollers and pass data between each other. For the purpose of keeping the example simple we define our view programmatically adding a few text fields and a button on the screens. The navigation controller displays the first view and then when the user clicks on the button it passes the data from the first view to the second view and if the user clicks on the back button of the navigation controller it calls the setScreenValues method defined in the protocol to pass the information back to the first screen. In the example we pass an object but you can pass simple String and integers using multiple parameters in the delegate method.
Interface file for the application delegate - PassingDataAppDelegate.h
#import <UIKit/UIKit.h> #import "FirstViewController.h" @interface PassingDataAppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (nonatomic, retain) UINavigationController *navigationController; @property (nonatomic, retain) FirstViewController *firstViewController; @end
Implementation file for the application delegate - PassingDataAppDelegate.m
#import "PassingDataAppDelegate.h" @implementation PassingDataAppDelegate @synthesize navigationController, firstViewController; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Override point for customization after application launch. //create the navigation controller and add to the view navigationController = [[UINavigationController alloc] init]; [self.window addSubview:[self.navigationController view]]; //check if the first viewcontroller eixsts, otherwise create it if(self.firstViewController == nil) { FirstViewController *firstView = [[FirstViewController alloc] init]; self.firstViewController = firstView; } //push the first viewcontroller into the navigation viewcontroller stack [self.navigationController pushViewController:self.firstViewController animated:YES]; self.window.backgroundColor = [UIColor whiteColor]; [self.window makeKeyAndVisible]; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { //do nothing } - (void)applicationDidEnterBackground:(UIApplication *)application { //do nothing } - (void)applicationWillEnterForeground:(UIApplication *)application { //do nothing } - (void)applicationDidBecomeActive:(UIApplication *)application { //do nothing } - (void)applicationWillTerminate:(UIApplication *)application { //do nothing } @end
Interface file for Country Object - Country.h
#import <Foundation/Foundation.h> @interface Country : NSObject @property NSString *code; @property NSString *name; @end
Implementation file for Country Object - Country.h
#import "Country.h" @implementation Country @synthesize code, name; @end
Interface file for First View Controller - FirstViewController.h
#import <UIKit/UIKit.h> #import "SecondViewController.h" #import "Country.h" //implements the second viewcontrollers "PassInformation" protocol @interface FirstViewController : UIViewController <PassInformation> @property (nonatomic, retain) SecondViewController *secondViewController; @property Country *country; @property UITextField *countryCode; @property UITextField *countryName; @end
Implementation file for First View Controller - FirstViewController.m
#import "FirstViewController.h" @interface FirstViewController () @end @implementation FirstViewController @synthesize countryCode,countryName; @synthesize country; @synthesize secondViewController; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization country = [[Country alloc] init]; } return self; } - (void)viewDidLoad { [super viewDidLoad]; NSLog(@"First view did load"); // Do any additional setup after loading the view. //set the title of the navigation view [self.navigationItem setTitle:@"First View"]; //set the background color of the view [self.view setBackgroundColor:[UIColor lightGrayColor]]; //create a text field for our country code and add to the view countryCode = [[UITextField alloc] init]; [countryCode setBorderStyle: UITextBorderStyleRoundedRect]; [countryCode setFrame:CGRectMake(10.0,10.0,200.0,30.0)]; [countryCode setPlaceholder:@"Enter Country Code here"]; [self.view addSubview: countryCode]; //create a text field for our country name and add to the view countryName = [[UITextField alloc] init]; [countryName setBorderStyle: UITextBorderStyleRoundedRect]; [countryName setFrame:CGRectMake(10.0,50.0,200.0,30.0)]; [countryName setPlaceholder:@"Enter Country Name here"]; [self.view addSubview: countryName]; //create a button so that when user clicks we can go to the next view UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; [button addTarget:self action:@selector(goToNextView:) forControlEvents:UIControlEventTouchDown]; [button setTitle:@"Next View" forState:UIControlStateNormal]; [button setBackgroundColor:[UIColor darkGrayColor]]; button.frame = CGRectMake(10.0, 90.0, 200.0, 30.0); [self.view addSubview:button]; } //action method linked to the button, gets called on the touchdown event - (void) goToNextView:(id)sender { //get reference to the button that requested the action UIButton *button = (UIButton *)sender; //check which button it is, if you have more than one button on the screen //you must check before taking necessary action if([button.currentTitle isEqualToString:@"Next View"]){ NSLog(@"Clicked on the button"); //if the second view controller doesn't exists create it if(self.secondViewController == nil){ SecondViewController *secondView = [[SecondViewController alloc] init]; self.secondViewController = secondView; } //set this view as the second viewcobntroller's delegate so that it can listen for events [secondViewController setDelegate:self]; //save the country object with screen values country.code = countryCode.text; country.name = countryName.text; //set the country object of the second view controller [self.secondViewController setCountry:country]; //tell the navigation controller to push a new view into the stack [self.navigationController pushViewController:self.secondViewController animated:YES]; } } //before the view appears check the country object and set the screen values - (void) viewWillAppear:(BOOL)animated { NSLog(@"First View will appear"); [countryCode setText:country.code]; [countryName setText:country.name]; } //delegate function implemented //this gets called from the second viewconroller when the view disappears - (void) setScreenValues:(Country *)myCountry { self.country = myCountry; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
Interface file for Second View Controller - SecondViewController.h
#import <UIKit/UIKit.h> #import "Country.h" //create this protocol so that we can pass information back @protocol PassInformation <NSObject> @optional -(void) setScreenValues:(Country *)myCountry; @end @interface SecondViewController : UIViewController @property Country *country; @property UITextField *countryCode; @property UITextField *countryName; //define the delegate property @property (nonatomic, unsafe_unretained) id<PassInformation> delegate; @end
Implementation file for Second View Controller - SecondViewController.m
#import "SecondViewController.h" @interface SecondViewController () @end @implementation SecondViewController @synthesize countryCode,countryName; @synthesize country; @synthesize delegate; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization country = [[Country alloc] init]; } return self; } - (void)viewDidLoad { [super viewDidLoad]; NSLog(@"Second view did load"); // Do any additional setup after loading the view. [self.navigationItem setTitle:@"Second View"]; [self.view setBackgroundColor:[UIColor lightGrayColor]]; countryCode = [[UITextField alloc] init]; [countryCode setBorderStyle: UITextBorderStyleRoundedRect]; [countryCode setFrame:CGRectMake(10.0,10.0,200.0,30.0)]; [countryCode setPlaceholder:@"Enter Country Code here"]; [self.view addSubview: countryCode]; countryName = [[UITextField alloc] init]; [countryName setBorderStyle: UITextBorderStyleRoundedRect]; [countryName setFrame:CGRectMake(10.0,50.0,200.0,30.0)]; [countryName setPlaceholder:@"Enter Country Name here"]; [self.view addSubview: countryName]; } - (void) viewWillAppear:(BOOL)animated { NSLog(@"Second View will appear"); [countryCode setText:country.code]; [countryName setText:country.name]; } - (void) viewWillDisappear:(BOOL) animated { NSLog(@"Second View will disappear"); country.code = countryCode.text; country.name = countryName.text; //Is anyone listening if([[self delegate] respondsToSelector:@selector(setScreenValues:)]) { //send the delegate function with the country information [[self delegate] setScreenValues:country]; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
No comments:
Post a Comment
NO JUNK, Please try to keep this clean and related to the topic at hand.
Comments are for users to ask questions, collaborate or improve on existing.