I have an application i am making but here is the problem which i been spedning hours figuring out.
I have a Tab-Based app, The first tab has a UILabel Object which should display an NSString from the SecondViewController.m which has a Method:
-(IBAction) save: (id) sender{
// This String holds data from the secondViewController's textfield to be passed to the
// UILabel whch is on the firsViewController.m
NSString *data = self.addDataTextfield.text;
}
I have used many methods including Singletons but they dont work as i have read somewhere that singletons are meant to pass data from Parent to child and child cant send data to the parent controller in this case BUT the Only way would be to use Protocols which i am but i am kind of lost using this method. Here is what i have on my secondViewController.h
#import <UIKit/UIKit.h>
#import "singletonObj.h"
#import "AppDelegate.h"
// Using a Protocol to pass data Back to the parent view
#protocol passStringDelegate <NSObject>
-(void) enteredString: (NSString *)string;
#end
#interface SecondViewController : UIViewController <UITextFieldDelegate>
{
singletonObj *object; // This singleton isnt being used, Just there incase
}
#property (strong, nonatomic)IBOutlet UITextField*addDataTextField;
- (IBAction)Save:(id)sender;
#property (retain) id <passStringDelegate> delegate;
#end
SO my Question is, is there any way i cando this and pass data from this secondViewController using #protocol or at least can anyone show me how to Use NSNotificationCenter within this code to pass data ? i dont feel comftarble using the AppDelegate class to pass data as it seems to go against apple's way or prepareforSegue which doesnt work for me.
I been searching around but most i find do the data being sent from the parent to the child but i dont see Tabbed based examples where the ChildViewController can send an NSString to the ParentViewController to display that data on an UILAbel.
There are several ways to do this. From any of the tab bar controller's content controllers, you can access another of the controllers with something like self.tabBarController.viewControllers[0]. This will reference the controller in the first tab. So, if you want to pass a string back to the first controller from the second, create a string property in the first controller (say, passedInString), and in the second controller, have something like this:
FirstViewController *first = self.tabBarController.viewControllers[0];
first.passedInString = self.stringToPass;
Ok #user2994008, in a UITabBarController app setup, I would not use a delegation pattern at forces coupling between the child view controllers in some manner. Posting a notification will get the job done, the only problem is what should trigger the notification to be posted. In this case, a quick and dirty way is to just post the notification in viewWillDisapper: as that will get called when the user switches tabs.
SecondViewController.m
//SecondViewController.m
//this is the view with the UITextField in it
#import "SecondViewController.h
#implementation SecondViewController
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSLog(#"%s", __FUNCTION__);
//since this gets called when the user switches tabs, i'll post the
//notification from this method
//retrieve our text field's text and store it in a dictionary
NSDictionary *dict = #{"text":self.addDataTextField.text};
//add the dictionary as userInfo: and post notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"myAwesomeNotification" object:nil userInfo:dict];
}
//all other second view controller methods here
#end
FirstViewController.m
//FirstViewController.m
#import "FirstViewController.h"
#implementation FirstViewController
-(void)viewDidLoad {
[super viewDidLoad];
//add an observer for the notification and tell it what method to call when it gets the notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(actionTriggeredByNotification:) name:#"myAwesomeNotification" object:nil];
}
- (void)actionTriggeredByNotification:(NSNotification*)notification {
NSLog(#"%s", __FUNCTION__);
NSDictionary *userInfo = [notification userInfo];
NSString *data = userInfo[#"text"];
NSLog(#"Text data is: %#", data);
}
- (void)dealloc {
//be sure to remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self];
//if using ARC, don't call super dealloc
}
//all other first view controller methods
#end
Also, drop the singleton stuff trying to pass data that way. That gets into trying to create what are in essence global variables and you don't really want that for passing simple strings around.
And while using notifications work ok here, some other solutions could be implemented using key-value observing (KVO) or adhering to the UITextFieldDelegate protocol and sending a message from one of those delegate methods. Even so, all these techniques still open up questions about when you actually want to retrieve the textfield's text.
Once you get your bearings, I'd HIGHLY recommend looking into ReactiveCocoa. It's a library designed specifically for solving problems like yours.
Related
I am trying to create a way to pass data from Controller A (CDCFaderController) to Controller B (CDCSendsViewController) this is because although Controller A owns a view, I need to send some of that views data to Controller B as it has some additional functionality I want to access.
My logic was to setup the delegate in Controller A and receive it in Controller B for use.
Currently I have this as a test to get it working:
Controller A .h
#protocol CDCSendsControllerDelegate <NSObject>
-(void)test:(NSString*)str;
#end
#interface CDCFaderController : UIViewController
<UIScrollViewDelegate, CDCControlDelegate, CDCFadersSideBarDelegate>
#property (nonatomic, weak) id <CDCSendsControllerDelegate> delegate; // delegate synthesis
Controller A .m
-(void)delegateTest {
[self.delegate test:#"Hello world!"];
}
And in the receiving Controller B:
Controller B .h
#interface CDCSendsViewController : UIViewController
<CDCControlDelegate, CDCSendsControllerDelegate>
Controller B .m
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"VDL CALLED");
CDCFaderController * faderController = [[CDCFaderController alloc] init];
faderController.delegate = self;
}
-(void) test:(NSString*)str{
NSLog(#"%#", str);
}
The idea i thought was that when i loaded Controller B it would pull through the print from Controller A and display the information?
In practice controller B wont be instantiated by the view as Controller A is the owner of the view. So I was wondering how to get B to call and pull data from A correctly to get this working? B is more of a background controller adding support functionality to A by using some of its passed data.
Hope this helps I can provide any further detail
I saw the above code. Actually your CDCFaderController is locally initialised in viewDidLoad method. ARC will release that controller object after viewDidLoad is executed as it is no longer used anywhere which will make the delegate nil as well.
Kindly make a property of CDCFaderController and initialise it. After that it should work fine.
I am new to objective C and trying to develop my own callback function, the callback function gets called on a particular event like receiving data from network like NSURLprotocol does and once received it will NSLog a message that "Event has Occured" or display as text on UIViewController or any UI related action.
So, I am totally confused as to where the eventOccuredMethod should be called to let the receiveController be called and execute the implementation inside it.
I have used protocols like NSURLProtocol before, but I don't know how to implement them to get such callbacks being called.
Any video links, answers, articles links are welcomed.
//Sample.h file
#import <Foundation/Foundation.h>
#class Sample;
#protocol SampleProtocol <NSObject>
-(void)receivedCallback;
#end
#interface Sample : NSObject
#property (nonatomic,weak) id<SampleProtocol> delegate;
-(void)eventOccured;
#end
//Sample.m file
#import "Sample.h"
#implementation Sample
-(void)eventOccured{
if([_delegate conformsToProtocol:#protocol(SampleProtocol)])
[_delegate receivedCallback];
}
#end
//ViewController.h file
#interface ViewController : UIViewController<SampleProtocol>
#end
//ViewController.m file
#import "ViewController.h"
#interface ViewController (){
Sample *s;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
s = [[Sample alloc] init];
s.delegate = self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)receivedCallback:(Sample *)sample{
NSLog(#"Event Has Occured");
}
#end
I am not sure of the following call which I am making ...
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
Sample *s = [[Sample alloc] init];
[s eventOccured];
}
You are implementing the delegate pattern the right way. But if the Sample object doesn't generate its own events but instead is relaying events posted to it from somewhere else, as is the case in your example, you have to ensure that the object which has the ViewController as a delegate and the object that receives the message are in fact the same. One way to do it is to make Sample a singleton :
#import "Sample.h"
#implementation Sample
+ (instancetype)sharedInstance
{
static id sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[[self class] alloc] init];
});
return sharedInstance;
}
-(void)eventOccured{
if([_delegate conformsToProtocol:#protocol(SampleProtocol)])
[_delegate receivedCallback];
}
#end
And then in your view controller you would do
s = [Sample sharedInstance];
and in your appDelegate :
[[Sample sharedInstance] eventOccured];
Another way to ensure that you are using the same object, as vikingosegundo pointed out, would be to set the view controller's Sample object from the appDelegate.
For this use case, you could also consider using Notifications.
?, i'm very confused. I don't think you understand what you have written. You should never try copy code like this from online without first reading a tutorial to understand what it is you are doing. This can be very dangerous.
Sample.h / .m is a class, this class defines a protocol that says "In order for me to alert you to the fact an event has occurred, you need to implement method X".
This is the "protocol", by conforming to the protocol, another class (lets say a ViewController) is saying that it implements the method that Sample is looking for.
So Sample will run code, and when it wants to pass some info back to the other class (ViewController in this case) it calls one of the methods defined in the protocol.
e.g. (not fully working code)
Sample.m
- (void)getDataFromURL:(NSStirng *)url
{
[self HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject)
{
if([_delegate conformsToProtocol:#protocol(SampleProtocol)])
{
[_delegate receivedCallback];
}
}];
}
So when Sample runs the method getDataFromURL it will request its data, when the data returns, Sample will call the method receivedCallback on its delegate. Which in this case is an instance of a viewController.
EDIT
please also note what [_delegate conformsToProtocol:#protocol(SampleProtocol)] does. This asks does the delegate instance conform to the protocol. But this protocol hasn't said that recievedCallback is required. So you have no way of knowing the method is there.
either use:
#protocol SampleProtocol <NSObject>
#required
-(void)receivedCallback;
#end
in the protocol definition or
if(self.delegate && [self.delegate respondsToSelector:#selector(receivedCallback)])
to check is it implemented
you are calling eventOccured on a second, independent Sample instance that has now delegate set.
The easiest fix: make the view controller send it to it's sample instance.
better: give the view controller a property that holds sample and sat that from the application delegate.
You should call EventOccurred within your data retrieving method. Once the data retrieving is complete call EventOccured.
#protocol SampleProtocol <NSObject>
-(void)receivedCallback;
#end
This protocol must be implemented in your data retrieving class. And make sure -(void)receivedCallback; has a parameter to send data to your ViewController
I have a simple test app to help me learn how to persist data from a NSMutableArray to a plist. Everything seems to be working well, until I try to save the data by calling a ViewController method called "saveData" in my AppDelegate.m file:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[ViewController saveData];
}
I get a "No known class method for selector 'saveData', although the method is clearly declared in ViewController.h, like so:
//
// ViewController.h
// PlistTest
//
// Created by Tim Jones on 10/30/13.
// Copyright (c) 2013 TDJ. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *nameLabel;
#property (weak, nonatomic) IBOutlet UILabel *timeLabel;
#property NSMutableArray *mainActivityArray;
- (IBAction)buttonHit:(id)sender;
-(NSString *) getFilePath;
-(void) saveData;
-(void) loadData;
#end
and implemented in ViewController.m, thusly:
//
// ViewController.m
// PlistTest
//
// Created by Tim Jones on 10/30/13.
// Copyright (c) 2013 TDJ. All rights reserved.
//
#import "ViewController.h"
#import "DataClass.h"
#interface ViewController ()
#end
#implementation ViewController
-(NSString *) getFilePath
{
NSArray *pathArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [[pathArray objectAtIndex:0] stringByAppendingPathComponent:#"PlistTestData"];
}
-(void) saveData
{
[self.mainActivityArray writeToFile: self.getFilePath atomically:YES];
}
I imported the ViewController.h into AppDelegate.h.
I'm pretty green, so I expect the problem may be obvious to many here. Would sure appreciate some help.
Issue:
[ViewController saveData];
You are calling saveData method using class name ViewController.
But saveData is an instance method, not class method.
-(void) saveData;
Fixes:
1) Declare saveData as class method
+(void) saveData;
2) Call saveData using the object of ViewController.
ViewController *vControl = [[ViewController alloc] init];
[vControl saveData];
Previous answer (Midhun #2) can work, but I think you would be better off using the Application Did Enter Background Notification and skip the delegate.
Just add this to "view did load": it will call saveData whenever the app goes to background.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(saveData) name:UIApplicationDidEnterBackgroundNotification object:nil];
Hope this helps.
As others have noted, your issue is that your [ViewController saveData] method invocation clearly suggests that you're trying to call a "class method", and you undoubtedly want to call your "instance method" (because it's your instance of your view controller that has the data you want to save). To achieve that, you have two basic choices:
You can have your app delegate call the saveData method in your view controller.
In various comments, you mention that you've "tried instantiating the VC every way and in every place I can imagine." Don't. Midhun's example was a conceptual one, illustrating the difference between a class and instance method. But, while you want to call the instance method, you want to call this for your existing instance of your view controller, definitely not instantiating a new view controller.
So, you may ask, how do you get a reference to the existing instance of your view controller? What you'll want to do is to (a) create a property in your app delegate to hold the reference to the view controller with the saveData method; (b) have that view controller set that property of the app delegate. So, first, create a property in your app delegate's .h file to reference the view controller:
#property (weak, nonatomic) ViewController *viewController;
Obviously, don't forget the #import "ViewController.h" line early in the .h file.
Second, have the viewDidLoad method of the view controller update the app delegate's viewController property:
- (void)viewDidLoad
{
[super viewDidLoad];
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
delegate.viewController = self;
}
Again, don't forget to #import "AppDelegate.h" at the top of your ViewController.m file.
Having done that, then app delegate's applicationDidEnterBackground can now reference this property that you set in viewDidLoad
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[self.viewController saveData];
}
Frankly, if you did this technique, I might suggest further refinements, notably employing a delegate-protocol pattern, but I'm going to defer that conversation until after you have mastered the above technique.
Even easier than the above is to eliminate this app delegate applicationDidEnterBackground code altogether, and just have your view controller, itself, respond to the system notification that is associated with the app entering background. And, needless to say, you put this code right in the view controller itself.
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(saveData) name:UIApplicationDidEnterBackgroundNotification object:nil];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
}
- (void)saveData
{
// save your data here
}
As you can see, I register to observe UIApplicationDidEnterBackgroundNotification in viewDidLoad, but also make sure to remove my observer in dealloc. I also made sure that my #selector method name exactly matched my method name (e.g., in my example, no parameters, and hence no colon).
I have an app that has multiple viewControllers, where some of these viewControllers contain methods that run various tasks. What I need to do is when the initial viewController loads, is to call these methods in the other viewControllers such that they run in the background, however, I am having some difficulty doing this.
Let's say I have 4 viewControllers, A, B, C, & D, where A is the initial viewController, and in each viewController, I have aMethod, bMethod, cMethod, and dMethod respectively. Here is the relevant code:
Inside my opening viewController (AviewController):
in the .h file:
#import "BViewController"
#import "CViewController"
#import "DViewController"
#interface AViewController:UIViewController {
BViewController *bViewCon;
CViewController *cViewCon;
DViewController *dViewCon;
}
#property (nonatomic, retain) BViewController *bViewCon;
#property (nonatomic, retain) CViewController *cViewCon;
#property (nonatomic, retain) DViewController *dViewCon;
#end
In my .m file I have the following:
#import "BViewController"
#import "CViewController"
#import "DViewController"
#implementation AviewController
#synthesize bViewCon, cViewCon, dViewCon;
- (void) viewDidLoad {
[super viewDidLoad];
bViewCon = [[BViewController alloc] init];
[bViewCon bMethod];
...
}
However, I am getting the error message, "No visible #interface for 'BViewController' declares the selector 'bMethod'". I need to call the other methods from the other viewControllers the same way from this class (i.e. AViewController).
Thanks in advance to all who reply.
Have you considered using NSNotificationCenter? Set up the methods on the notifications and just ping them when you need them to run. This helps if your other view controller is instantiated and available, like buried in the navigation controller stack or on a separate tab.
To answer you question about that error, you need to declare the method you want to call in your header file. The error is stating it can't find a declaration for that method.
Example of notification center
// listen for notifications - add to view controller doing the actions
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(mySpecialMethod) name:#"SomeNotificationName" object:nil];
// when you want your other view controller to do something, post a notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"SomeNotificationName" object:nil];
// you don't want this notification hanging around, so add this when you are done or in dealloc/viewDidUnload
[[NSNotificationCenter defaultCenter] removeObserver:self]; // this removes all notifications for this view
// if you want to remove just the one you created, you can remove it by name as well
To solve the error you're receiving, make sure that all of the methods are declared in the header (.h) files of each controller (otherwise, the compiler won't be able to see them).
As all of these controllers are children to AViewController (they are created by AViewController and kept as ivars on it), I wouldn't use NSNotificationCenter here (unless there are other objects that need to be notified in case of certain events occurring too, which aren't owned by AViewController).
Instead, I would just call the methods directly as you're attempting to do.
On another note, if these methods are starting ongoing tasks (running tasks in background), it may be best for you to move the method calls to the init: method of AViewController. (As on iOS 5, views CAN be unloaded and hence viewDidLoad: can be called potentially more than once... such as in the case of memory warnings and the view being off screened). I might go about doing something like this:
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle
{
self = [super initWithNibName:nibName bundle:bundle]; // your correct stuff here
if (self)
{
bViewCon = [[BViewController alloc] init];
[bViewCon bMethod];
// ... and so on for the other controllers
}
return self;
}
Edit
Although, as mentioned in a comment, UIViewControllers aren't exactly cheap in terms of memory... it honestly would likely be best to refactor this code to have a single controller (a subclass of NSObject instead of UIViewController, which is cheaper) to act as a manager for the tasks that are going to be running in the background. I imagine this will likely help you later down the road too, as it would help compartmentalize the tasks and purpose of each of your controllers (in such, UIViewControllers should primarily be responsible for managing a view (/view hierarchy in some cases) and associated tasks... if there are ongoing tasks that are occurring outside the scope of things associated with said view, it's probably a sign that the UIViewController shouldn't be handling them...
This question already has answers here:
How do I create delegates in Objective-C?
(20 answers)
Closed 9 years ago.
What is a "delegate" in Objective C's iPhone development?
A delegate is a pointer to an object with a set of methods the delegate-holder knows how to call. In other words, it's a mechanism to enable specific callbacks from a later-created object.
A good example is UIAlertView. You create a UIAlertView object to show a short message box to users, possibly giving them a choice with two buttons like "OK" and "Cancel". The UIAlertView needs a way to call you back, but it has no information of which object to call back and what method to call.
To solve this problem, you can send your self pointer to UIAlertView as a delegate object, and in exchange you agree (by declaring the UIAlertViewDelegate in your object's header file) to implement some methods that UIAlertView can call, such as alertView:clickedButtonAtIndex:.
Check out this post for a quick high-level intro to the delegate design pattern and other callback techniques.
References:
UIAlertView class reference
UIAlertViewDelegate class reference
Apple's guide to Delegates and Data sources
See this discussion
A delegate allows one object to send messages to another object when an event happens. For example, if you're downloading data from a web site asynchronously using the NSURLConnection class. NSURLConnection has three common delegates:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
One or more of these delegates will get called when NSURLConnection encounters a failure, finishes successfully, or received a response from the web site, respectively.
Delegates are a design pattern; there is no special syntax or language support.
A delegate is just an object that another object sends messages to when certain things happen, so that the delegate can handle app-specific details the original object wasn't designed for. It's a way of customizing behavior without subclassing.
I think this Wikipedia article describes it best: http://en.wikipedia.org/wiki/Delegation_pattern
It is "just" an implementation of a design pattern and very common in Objective-C
I think all these answers make a lot of sense once you understand delegates. Personally I came from the land of C/C++ and before that procedural languages like Fortran etc so here is my 2 min take on finding similar analogues in C++ paradigm.
If I were to explain delegates to a C++/Java programmer I would say
What are delegates ? These are static pointers to classes within another class. Once you assign a pointer, you can call functions/methods in that class. Hence some functions of your class are "delegated" (In C++ world - pointer to by a class object pointer) to another class.
What are protocols ? Conceptually it serves as similar purpose as to the header file of the class you are assigning as a delegate class. A protocol is a explicit way of defining what methods needs to be implemented in the class who's pointer was set as a delegate within a class.
How can I do something similar in C++? If you tried to do this in C++, you would by defining pointers to classes (objects) in the class definition and then wiring them up to other classes that will provide additional functions as delegates to your base class. But this wiring needs to be maitained within the code and will be clumsy and error prone. Objective C just assumes that programmers are not best at maintaining this decipline and provides compiler restrictions to enforce a clean implementation.
I try to elaborate it through simple program
Two Classes
Student.h
#import <Foundation/Foundation.h>
#interface Student : NSObject
#property (weak) id delegate;
- (void) studentInfo;
#end
Student.m
#import "Student.h"
#implementation Student
- (void) studentInfo
{
NSString *teacherName;
if ([self.delegate respondsToSelector:#selector(teacherName)]) {
teacherName = [self.delegate performSelector:#selector(teacherName)];
}
NSLog(#"\n Student name is XYZ\n Teacher name is %#",teacherName);
}
#end
Teacher.h
#import <Foundation/Foundation.h>
#import "Student.h>
#interface Teacher: NSObject
#property (strong,nonatomic) Student *student;
- (NSString *) teacherName;
- (id) initWithStudent:(Student *)student;
#end
Teacher.m
#import "Teacher.h"
#implementation Teacher
- (NSString *) teacherName
{
return #"ABC";
}
- (id) initWithStudent:(Student *)student
{
self = [ super init];
if (self) {
self.student = student;
self.student.delegate = self;
}
return self;
}
#end
main.m
#import <Foundation/Foundation.h>
#import "Teacher.h"
int main ( int argc, const char* argv[])
{
#autoreleasepool {
Student *student = [[Student alloc] init];
Teacher *teacher = [[Teacher alloc] initWithStudent:student];
[student studentInfo];
}
return 0;
}
EXPLANATION :::
From main method when initWithStudent:student will execute
1.1 Teacher's object's property 'student' will be assigned with student object.
1.2 self.student.delegate = self
means student object's delegate will points to teacher object
From main method when [student studentInfo] will be called
2.1 [self.delegate respondToSelector:#selector(teacherName)]
Here delegate already points to teacher object so it can invoke
'teacherName' instance method.
2.2 so [self.delegate performSelector:#selector(teacherName)]
will execute easily.
It looks like Teacher object assign delegate to student object to call it's own method.
It is a relative idea, where we see that student object called 'teacherName' method but it is basically done by teacher object itself.
Please! check below simple step by step tutorial to understand how Delegates works in iOS.
Delegate in iOS
I have created two ViewControllers (for sending data from one to another)
FirstViewController implement delegate (which provides data).
SecondViewController declare the delegate (which will receive data).
Here is the sample code may help you.
AppDelegate.h
#import <UIKit/UIKit.h>
#class FirstViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#property (strong, nonatomic) FirstViewController *firstViewController;
#end
AppDelegate.m
#import "AppDelegate.h"
#import "FirstViewController.h"
#implementation AppDelegate
#synthesize firstViewController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
//create instance of FirstViewController
firstViewController = [[FirstViewController alloc] init];
//create UINavigationController instance using firstViewController
UINavigationController *firstView = [[UINavigationController alloc] initWithRootViewController:firstViewController];
//added navigation controller to window as a rootViewController
self.window.rootViewController = firstView;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
#end
FirstViewController.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface FirstViewController : UIViewController<MyDelegate>
#property (nonatomic, retain) NSString *mesasgeData;
#property (weak, nonatomic) IBOutlet UITextField *textField;
#property (weak, nonatomic) IBOutlet UIButton *nextButton;
- (IBAction)buttonPressed:(id)sender;
#property (nonatomic, strong) SecondViewController *secondViewController;
#end
FirstViewController.m
#import "FirstViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
#synthesize mesasgeData;
#synthesize textField;
#synthesize secondViewController;
#pragma mark - View Controller's Life Cycle methods
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - Button Click event handling method
- (IBAction)buttonPressed:(id)sender {
//get the input data from text feild and store into string
mesasgeData = textField.text;
//go keypad back when button clicked from textfield
[textField resignFirstResponder];
//crating instance of second view controller
secondViewController = [[SecondViewController alloc]init];
//it says SecondViewController is implementing MyDelegate
secondViewController.myDelegate = self;
//loading new view via navigation controller
[self.navigationController pushViewController:secondViewController animated:YES];
}
#pragma mark - MyDelegate's method implementation
-(NSString *) getMessageString{
return mesasgeData;
}
#end
SecondViewController.h
//declare our own delegate
#protocol MyDelegate <NSObject>
-(NSString *) getMessageString;
#end
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *messageLabel;
#property (nonatomic, retain) id <MyDelegate> myDelegate;
#end
SecondViewController.m
#import "SecondViewController.h"
#interface SecondViewController ()
#end
#implementation SecondViewController
#synthesize messageLabel;
#synthesize myDelegate;
- (void)viewDidLoad
{
[super viewDidLoad];
messageLabel.text = [myDelegate getMessageString];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
The delegate fires the automatic events in Objects C. If you set the delegate to Object, it sends the message to another object through the delegate methods.
It's a way to modify the behavior of a class without requiring subclassing.
Each Objects having the delegate methods.These delegate methods fires, when the particular Objects take part in user interaction and Program flow cycle.
Simply stated: delegation is a way of allowing objects to interact with each other without creating strong interdependencies between them.
A delegate captures the taping actions of an user and performs particular Action according to the user Taping Action.
Delegate is nothing but instance of Object which we can call methods behalf of that Objects. and also helps to create methods in rumtime of that Objects.