I am a newbie to iOS world, so please ignore the obvious.
I am pushing a viewController(HelpViewController) on top of another viewController(MainViewController). When a particular action happens in the HelpViewController, I would like to update a variable inside the MainViewController. I understand for this I need to use delegate.
Here is my delegate header...
#protocol ViewControllerDelegate <NSObject>
#required
- (void) switchToggled:(BOOL)status;
#end
// Protocol Definition ends here
#interface ViewDelegate : NSObject
{
// Delegate to respond back
id <ViewControllerDelegate> _delegate;
}
#property (nonatomic,strong) id delegate;
-(void)sendMessage:(BOOL)status; // Instance method
#end
and implementation...
#implementation ViewDelegate
#synthesize delegate;
-(id)init {
self = [super init];
return self;
}
-(void)sendMessage:(BOOL)status
{
[delegate switchToggled:status];
}
- (void)dealloc
{
[super dealloc];
}
#end
So Now If I want to implement Protocol ViewControllerDelegate I need to specify in MainViewController, which I do as follows --
MainViewController <ViewControllerDelegate>
and
#pragma mark - ViewControllerDelegate delegate
-(void)switchToggled:(BOOL)status{
NSLog(#"Switch Toggled(%d) Message passed to MainViewController",status);
}
My question is how do I specify Object, which delegate property needs to point to, so that it can come back to MainViewController's "switchToggled".
One way I do is by having property inside HelpViewController as follows -
MainViewController.m
HelpViewController *helpVC = [[HelpViewController alloc] init];
helpVC.mainView = self;
[self.navigationController pushViewController:helpVC animated:YES];
[helpVC release];
HelpViewController.h
#property (nonatomic) MainViewController *mainView;
HelpViewController.m
#synthesize mainView;
ViewDelegate *myDelegate = [[ViewDelegate alloc] init];
// assign delegate
myDelegate.delegate = mainView;
[myDelegate sendMessage];
[myDelegate release];
Is this correct way to implement or there is better way to achieve this or am I totally wrong.
Thanks
You should do:
// HelpViewController.h
#protocol HelpDelegate
- (void)switchToggled:(BOOL)status;
#end
// HelpViewController.m
#interface HelpViewController : UIViewController
#property (nonatomic, assign) id<HelpDelegate> delegate;
- (id)initWithDelegate:(id<HelpDelegate>)delegate
#end
#implementation HelpViewController
- (id)initWithDelegate:(id<HelpDelegate>)delegate
{
if (self = [super init])
{
self.delegate = delegate;
}
}
- (void)sendMessage:(BOOL)status
{
[self.delegate switchToggled:status];
}
// MainViewController.h
#import "HelpViewController.h"
#interface MainViewController.h : UIViewController <HelpDelegate>
// MainViewController.m
- (void)someMethod
{
HelpViewController* viewController;
viewController = [HelpViewController alloc] initWithDelegate:self];
...
}
#pragma mark - Help Delegate
- (void)switchToggled:(BOOL)status
{
...
}
Give the delegate a name that makes clear to which class it belongs.
You don't need the extra class/files for ViewDelegate/ViewControllerDelegate. Just define the delegate in header of class it belongs to: HelpViewController.n in this case.
Similar: Implement the delegate method switchToggled: in the real class MainViewController, and not in the extra/unnecessary class ViewDelegate.
The purpose of delegates is to avoid class dependencies. By including MainViewController in HelpViewController you create such a dependency. This is not necessary as I show, and is wrong design.
You were also creating a circular dependency, because MainViewController already needed HelpViewController in order to show it, and now they need each other the other way around for sending the event.
Alternatively you can make HelpViewController's delegate public, have an init without argument, and expect users to set it with helpViewController.delegate = self; or something. But this would only make sense when the delegate being set is optional (which don't seems the case here, so adding it to the init method is appropriate).
I tell you what I would have done:
1) the protocol definition is ok, but do NOT create the class ViewDelegate, so:
//ViewControllerDelegate.h
#protocol ViewControllerDelegate <NSObject>
#required
- (void) switchToggled:(BOOL)status;
#end
2) Your implementation of the delegate method in MainViewController is ok.
3) Now... the important point:
//interface
#interface HelpViewController : UIViewController //or whatever superclass..
{
id <ViewControllerDelegate> _delegate;
}
#property (nonatomic,strong) id<ViewControllerDelegate> delegate;
#end
//implementation
#implementation HelpViewController
- (void)someMethodWhichCallsTheDelegate
{
//do something
...
// call delegate
//if switchToggled: were optional then add the following
//if ([self.delegate respondToSelector:#selector(switchToggled:)]) {
[self.delegate switchToggled:status];
}
#end
4) Now you have to assign the delegate:
//MainViewController.m
HelpViewController *helpVC = [[HelpViewController alloc] init];
helpVC.delegate = self;
[self.navigationController pushViewController:helpVC animated:YES];
[helpVC release];
And that's it!
BTW: if this delegate is related only to HelpViewControllerthen add the protocol definition where you define the interface of the class, it is not necessary to create a separate header file. If instead the protocol is "global", then it can have some sense to declare it separately.
Related
I started testing ECSlidingViewController and after I tried to access FirstTopViewController I have a big trouble - because in FirstToViewController I already have ZBarReaderDelegate implemented and all examples of delegate are not triggering any method from my delegate.
Basically I have this stuff:
FirstTopViewController.h
#import ...MyStuff...
#import "UnderRightViewController.h"
#interface FirstTopViewController : UIViewController <RightViewDelegate, ZBarReaderDelegate>
#property (weak, nonatomic) IBOutlet UITextView *labelTotal;
#end
FirstTopViewController.m
#import "FirstTopViewController.h"
#implementation FirstTopViewController
- (void)setTotalViewController:(UnderRightViewController*)controller didTotalChange:(NSString*)total
{
//labelTotal.text = total;
NSLog(#"I'm here!!! and received %#", total);
}
From other side I have
UnderRightViewController.h
#import <UIKit/UIKit.h>
#import "ECSlidingViewController.h"
#class UnderRightViewController;
#protocol RightViewDelegate <NSObject>
- (void)setTotalViewController:(UnderRightViewController*)controller didTotalChange:(NSString*)total;
#end
#interface UnderRightViewController : UITableViewController
#property (nonatomic, weak) id <RightViewDelegate> delegate;
#end
UnderRightViewController.m
#import "UnderRightViewController.h"
#interface UnderRightViewController ()
#end
#implementation UnderRightViewController
#synthesize delegate;
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[delegate setTotalViewController:self didTotalChange:#"foo"];
}
#end
I'm trying this entire day solve this puzzle but I never get setTotalViewController fired.
Thanks in advance.
Friend you did a small mistake, when you navigate from FirstTopViewController to UnderRightViewController at that time you need to do this in FirstTopViewController.m:-
UnderRightViewController *obj = [[UnderRightViewController
alloc] initWithNibName:#"UnderRightViewController" bundle:nil];
obj.delegate = self; // u forget to assign protocol handler
[self.navigationController pushViewController:obj animated:YES];
[obj release];
You don't have any code that is setting the delegate for the UnderRightViewController. I don't know what object owns both of these controllers, but before either UnderRightViewController and FirstTopViewController are displayed it should run code something like this:
FirstTopViewController *ftvc = //... where ever you get a reference to this from
UnderRightViewController *urvc = ...;
urvc.delegate = ftvc;
In your above code you are using custom delegates and also you have used it for sending message to onecontroller class to another controller class. So below is the same sample code of custom delegates, it is working fine in similar way you have to implement and also the problem in your code is you are not setting the delegate, so please follow below how to set the same and call the method. here i have used your same method only return type i have defined as NSString in-spite of void for explaining purpose, but you can use void according to your requirement hope it will be helpful to you:-
First Controller Class AWindowController.h
#interface AWindowController : NSWindowController<sampleDelegate>
{
NSString *textA;
}
#property(readwrite,retain)NSString *textA;
-(IBAction)doSet:(id)sender;
#end
#import "AWindowController.h"
#import "BWindowController.h"
#interface AWindowController ()
#end
#implementation AWindowController
#synthesize textA;
- (id)initWithWindow:(NSWindow *)window
{
self = [super initWithWindow:window];
if (self) {
// Initialization code here.
}
return self;
}
- (NSString *)setTotalViewController:(BWindowController*)controller didTotalChange:(NSString*)total
{
NSLog(#"recieved");
return #"recieved";
}
- (void)windowDidLoad
{
[super windowDidLoad];
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
-(NSString*)windowNibName
{
return #"AWindowController";
}
-(IBAction)doSet:(id)sender
{
[self setTextA:#"Awindow Button Pressed"];
BWindowController *b=[[BWindowController alloc]init];
b.delegate=self;
[b showWindow:self];
}
#end
Second Controller Class BWindowController.h
#import <Cocoa/Cocoa.h>
#import "sampleDelegate.h"
#class BWindowController;
#protocol sampleDelegate <NSObject>
#required
//-(NSString *)getDataValue;
- (NSString *)setTotalViewController:(BWindowController*)controller didTotalChange:(NSString*)total;
#end
#interface BWindowController : NSWindowController<sampleDelegate>
{
NSString *bTextValue;
id<sampleDelegate>delegate;
}
#property(readwrite,retain)NSString *bTextValue;
#property(readwrite,assign)id<sampleDelegate>delegate;
#end
#import "BWindowController.h"
#interface BWindowController ()
#end
#implementation BWindowController
#synthesize bTextValue,delegate;
- (id)initWithWindow:(NSWindow *)window
{
self = [super initWithWindow:window];
if (self) {
// Initialization code here.
}
return self;
}
- (NSString *)setTotalViewController:(BWindowController*)controller didTotalChange:(NSString*)total;
{
return nil;
}
- (void)windowDidLoad
{
NSString *str= [[self delegate]setTotalViewController:self didTotalChange:#"recieved"];
self.bTextValue=str;
[super windowDidLoad];
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
-(NSString*)windowNibName
{
return #"BWindowController";
}
#end
Attached screen shot in Output:-
Below is window is the AwindowController.h class
Below in the same above window pressing the button and when Awindow button pressed data will send
and notification will be recieved in Bwindow using above define custom delegates as attached in the screen shot.
I have a UIViewController on a UINavigationStack and from this UIView I load another view not onto the stack but as a subview. This view that I load is just a preferences view for the app that I overlay onto what ever is showing.
i.e.
myViewController <- on the stack button touch loads as a subview to myViewController
+ prefrencesViewController
My question is, is there a way to call a method thats in myViewController from prefrencesViewController? I am trying to use delegates and protocols but its not working, so I am hoping there is either an easy way to do this I don't know about yet or maybe I could get some help with my delegate/protocol...
This is what my code looks like for delegate and protocol set up
//prefrencesViewController.h
#protocol GetPrefrencesViewControllerDelegate <NSObject>
-(void)reloadViewFromSavedPrefrences;
#end
//delegates and protocols
#property (nonatomic, weak) id <GetPrefrencesViewControllerDelegate> delegate;
//prefrencesViewController.m
//delegates and protocols
#synthesize delegate;
//.. inside button action
[[self delegate] reloadViewFromSavedPrefrences];
//myViewController.h
#import "prefrencesViewController.h"
#interface myViewController : UIViewController <UITabBarDelegate, GetGUIEncodedData, GetPrefrencesViewControllerDelegate> {
// prefrencesViewController set up
prefrencesViewController *pvc;
#property (strong, nonatomic) prefrencesViewController *pvc;
//myViewontroller.h
#synthesize pvc;
- (void)viewDidLoad
{
//..
[pvc setDelegate:self];
}
//Delegate and prefrences.. Saved pressed reload the view here.
-(void)reloadViewFromSavedPrefrences {
NSLog(#"WORKED");
}
any help would be greatly appreciated
I'm not sure that you are following the steps that I will present below but if you don't here is the example.
PresentedViewController.h
//import stuff
#protocol PresentedViewControllerDelegate <NSObject>
-(void)methodThatSouldBeImplementedByOtherController; //you can add params
#end
#interface PresentedViewController : UIViewController {
//instance variables
}
#property (nonatomic, assign(week for ARK)) id<PresentedViewControllerDelegate>delegate
//public methods here
PresentedViewController.m
#implementation PresentedViewController
#synthesize delegate;
//method implementation here
-(IBAction)buttonThatWillCallTheDelegate:(id)sender {
if([self.delegate respondsToSelector:#selector(methodThatSouldBeImplementedByOtherController)]) {
[self.delegate methodThatSouldBeImplementedByOtherController];
}
}
ControllerThatWillPresent.h
#interface ControllerThatWillPresent : UIViewController <PresentedViewControllerDelegate> {
//instance variables
}
//some methods maybe
ControllerThatWillPresen.m
#implementation ControllerThatWillPresen
-(void)methodThatWillShowTheVC {
PresentedViewController *vc = [PresentedViewController alloc] init]; //initWithNibname...
vc.delegate = self;
//presentVc, pushVc, addChild ...
}
-(void)methodThatSouldBeImplementedByOtherController {
//do stuff in delegate method
}
I am building a utility application which shares data between main view and flip view. Actually, it is not exactly the flip view that's holding data, it's the custom view that's an instance of the flip view when it gets loaded. I have explained the specifics in my previous thread here, but I haven't got a solution yet. And I have redeveloped my code, hopefully this time I could make myself clear.
The general concept here is I create and store data in my main view, and pass it to the flip side view using the predefined delegate in the FlipViewController. Then in the FlipViewController, I store the data in my own delegate and pass it to the custom view which implements my own delegate method. The following is the main portions of the code.
MainViewController.m (only adopts <FlipsideViewControllerDelegate> protocol)
- (IBAction)showInfo:(id)sender {
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
controller.chart = data;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
FlipsideViewController.h
#protocol FlipsideViewControllerDelegate;
#protocol ChartDelegate;
#interface FlipsideViewController : UIViewController {
id <FlipsideViewControllerDelegate> delegate;
id <ChartDelegate> delegate2;
DataModel *chart;
}
#property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;
#property (nonatomic, assign) id <ChartDelegate> delegate2;
#property (nonatomic, retain) DataModel *chart;
- (IBAction)done:(id)sender;
#end
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
#end
#protocol ChartDelegate <NSObject>
- (void)getParams:(DataModel *)dataModel;
#end
FlipsideViewController.m
#synthesize delegate, delegate2;
#synthesize chart;
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor];
if ([delegate2 respondsToSelector:#selector(getParams:)]) {
[delegate2 getParams:chart];
}
}
customDrawing.h
#interface customDrawing : UIView <ChartDelegate>{
DataModel *chartData;
}
#property (nonatomic, retain) DataModel *chartData;
#end
customDrawing.m
#synthesize chartData;
-(void)getParams:(DataModel *)dataModel{
chartData = dataModel;
}
It turns out the data didn't get passed to the chartData object in my custom view. HELP?
You are missing the fundamentals. I do not think you need delegates to achieve this task but here we go.
A protocol is like a contract. In you FlipsideViewController class you defined the protocol which essentially states if you conform to this protocol then you must implement this method.
How do you conform to a protocol?
In MainViewController the #interface will look something like this
#interface MainViewController : UIViewController <FlipsideViewControllerDelegate>
The fact that you have the protocol written in angled brackets means that you promise to conform to the protocol and therefore have to implement
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
in your MainViewController.m.
Now when MainNavigationController set's itself as the delegate (controller.delegate = self;) it finishes the link. This allows the FlipsideViewController to call
[delegate flipsideViewControllerDidFinish:self];
Which will call the method defined in MainViewController which dismisses the modal view controller.
You have defined a second protocol (you could have added the method to the first and then you would not have to adopt two protocols) and as others have pointed out you have not linked the classes up by doing
controller.delegate2 = self;
This would not solve your problem. You would still need to conform to the ChartDelegate by adding it to the declaration. Once you have done that you will still not be out of the water because the method is not correct.
Full solution - not using delegates as they are not really required here
MainViewController.h
#interface MainViewController : UIViewController <FlipsideViewControllerDelegate>
- (IBAction)showInfo:(id)sender;
#end
MainViewController.m
#implementation MainViewController
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction)showInfo:(id)sender
{
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
controller.delegate = self;
/*
* The labelText property is defined in the header for FlipsideViewController
* In this case this is the easiest way to get data from this controller to
* the controller we are about to display
*/
controller.labelText = #"WHAT EVER YOU WANT TO SEND"; // <---- sending data
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:controller animated:YES];
[controller release];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
FlipsideViewController.h
#class FlipsideViewController;
#protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
#end
#interface FlipsideViewController : UIViewController
/*
* These properties have been added. The label is used for displaying the text
* and needs to be hooked up in Interface builder
*
* The NSString is the property that is holding the data passed from MainViewController
*/
#property (nonatomic, retain) IBOutlet UILabel *testLabel;
#property (nonatomic, copy) NSString *labelText; from MainViewControlller
#property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;
- (IBAction)done:(id)sender;
#end
FlipsideViewController.m
#implementation FlipsideViewController
#synthesize delegate = _delegate;
/*
* We need to synthesise out properties so we get our getters and setters created
*/
#synthesize testLabel = _testLabel;
#synthesize labelText = _labelText;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
/*
* This is called once the view is set up and all connections have been made in
* interface builder. Therefore we can now set the text of our test label
*/
self.testLabel.text = labelText;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Actions
- (IBAction)done:(id)sender
{
[self.delegate flipsideViewControllerDidFinish:self];
}
- (void)dealloc
{
/*
* Memory management for the ivars we added
*/
[_testLabel release];
[_labelText release];
[super dealloc];
}
#end
You have two properties: delegate and delegate2. You are assigning a value to delegate, but calling the method on delegate2 later.
You need to assign the delegate2 (your customDrawing class). You are only assigning the delegate.
Sorry if the question is not to clear, this is what im trying to do. I have an object, a delegate and a view controller.
Object pseudo-code
#interface Car: NSObject {
UIColor *color;
}
#property (assign)UIColor *color;
- (void) setColor(UIColor col);
#end
#implementation Car
#synthetize color;
// i know that synthesize makes this function redundant.
// I just used it to demonstrate
// the need to access an instance method.
- (void) setColor(UIColor col)
{
color = col;
}
#end
delegate code
#interface myDelegate: UIApplicationDelegate {
Car *car;
UIViewController *theView;
}
#property (assign)Car *car;
#end
#implementation myDelegate
#synthesize car;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
theView = [[MyViewController alloc]init];
return YES;
}
#end
View pseudo Code
#interface MyViewController: UIViewController {
MyDelegate *appDelegate;
}
#property (retain) MyDelegate *appDelegate;
#end
#implementation MyViewController
#synthesize appDelegate;
- (void)viewDidLoad {
self.appDelegate = (MyDelegate*)[[UIApplication sharedApplication] delegate];
/// THIS IS MY ISSUSE!
[self.appDelegate.car setColor(UIColor);
}
#end
Can anyone explain or point me to where i can understand why [self.appDelegate.car setColor()] gives me a compile error that reads "Unknown component setColor of a property".
Im sure there is a way to do this in objective C as i would do it in python, java or other OO language.
Any help would be greatly appreciated
Cheers
Rudy
You are not using UIColor as a pointer.
Try using UIColor * instead of just UIColor and the compiler will stop complaining
First of all, the Car class has problems. The color property should be defined as retain, not assign. assign is generally for non-object type properties, such as an NSInteger, BOOL, int, etc., and for a special case of objects that shouldn’t be retained because they’d create retain cycles. Also, - (void)setColor(UIColor col); is not a valid method name, as it is written as if it were a function. In Objective-C, each parameter is preceded by a colon :.
For example, take the following method:
- (void)setBodyColor:bodyColor lowerColor:lowerColor upperColor:upperColor;
While that is technically a valid method signature, it is generally written differently to make its usage more clear. As it’s defined above, each parameter is of type id, which is a generic object type. To make things clearer, you cast each argument to the type of objects they represent:
- (void)setBodyColor:(UIColor *)bodyColor
lowerColor:(UIColor *)lowerColor
upperColor:(UIColor *)upperColor;
In addition to being defined incorrectly, it’s also superfluous since defining a read-write property named color implies that a -setColor: method will be defined. The code would look like this:
#interface Car: NSObject {
UIColor *color;
}
#property (retain) UIColor *color;
#end
#implementation Car
#synthetize color;
- (void)dealloc {
[color release];
[super dealloc];
}
// If you need to override a method, that’s fine
- (void) setColor:(UIColor *)aColor
{
[aColor retain];
[color release];
color = aColor;
// do more stuff
}
#end
On to your delegate, it also has problems. First, myDelegate is defined as a subclass of UIApplicationDelegate, which is not even a class: it’s a protocol (or interface) that other objects can conform to. The car property should also be defined as retain, since it’s an object that your app delegate owns. Here, theView (which should likely be renamed to something like theViewController) should be typed as MyViewController to make it more clear.
#interface MyDelegate : NSObject <UIApplicationDelegate> {
Car *car;
MyViewController *theView;
}
#property (retain) Car *car;
#end
#implementation MyDelegate
#synthesize car;
- (void)dealloc {
[car release];
[theView release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
theView = [[MyViewController alloc] init];
return YES;
}
#end
The MyViewController class has problems in that the appDelegate is defined as retain when it should likely be assign. The app delegate itself is creating the view controller using alloc/init, meaning the app delegate “owns” the view controller. The view controller shouldn’t retain the app delegate because that would create a retain cycle (see Retain Cycles).
MyViewController.h
// forward declaration
#class MyDelegate;
#interface MyViewController: UIViewController {
MyDelegate *appDelegate; // non-retained
}
#property (assign) MyDelegate *appDelegate;
#end
MyViewController.m
#import "MyViewController.h"
#import "MyDelegate.h"
#implementation MyViewController
#synthesize appDelegate;
- (void)viewDidLoad {
self.appDelegate = (MyDelegate*)[[UIApplication sharedApplication] delegate];
[self.appDelegate.car setColor:[UIColor clearColor]];
/// THIS IS MY ISSUSE!
// [self.appDelegate.car setColor(UIColor);
}
#end
I've created a protocol named RecDelegate that's consisted of a method "- (void) doSmtng".
The protocol is defined in rec.h just before the rec interface declaration.
When I create a new application and adopt the RecDelegate to the new appDelegate, I can implement my own doSmtng, as needed to be.
What I don't understand is how can I invoke the doSmtng method from the rec.m (implementation of the class in which the protocol is defined...) - Meaning, how can I "Fire" the doSmtng in such a way that the new appDelegate's implementation will be triggered.
Hope what I said is relatively clear ... ;)
Thanks,
Guy.
There are two controllers below showing how to trigger an event from one to the other.
Wherever there is a comment "//HERE", it indicates there is delegation-related code.
SENDER OF DELEGATE
SecondViewController.h
#import <UIKit/UIKit.h>
#protocol SecondDelegate <NSObject> // HERE
#optional
-(void)MessageReceived:(NSString *)msg;
#end
#interface SecondViewController : UIViewController {
id<SecondDelegate> secondDelegate; // HERE
}
#property (assign) id<SecondDelegate> secondDelegate; // HERE
-(IBAction)trigger:(id)sender;
#end
SecondViewController.m
#import "SecondViewController.h"
#implementation SecondViewController
#synthesize secondDelegate; // HERE
-(IBAction)trigger:(id)sender {
if (self.secondDelegate != NULL && [self.secondDelegate respondsToSelector:#selector(MessageReceived:)]) { // HERE
[secondDelegate MessageReceived:#"my message"];
}
}
RECEIVER OF DELEGATE
FirstViewController.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h" // HERE
#interface FirstViewController : UINavigationController <SecondDelegate> // HERE
-(void)MessageReceived:(NSString*)msg; // HERE
#end
FirstViewController.m
#import "FirstViewController.h"
#import "SecondViewController.h"
#implementation FirstViewController
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
[self.view setBackgroundColor:[UIColor greenColor]];
SecondViewController *second = [[SecondViewController alloc] init];
[self pushViewController:second animated:YES];
second.secondDelegate = self; // HERE
[second release];
}
return self;
}
-(void)MessageReceived:(NSString *)msg { // HERE
int y = 0; // HERE IT IS !
}
You need to tell your Rec object that it should treat your AppDelegate as its delegate:
[rec setDelegate:appDelegate];
This could be done via Interface Builder or just after the Rec object is created.
Then, when the Rec object sends the delegate message to its delegate, the receiver will be your AppDelegate instance:
[[self delegate] doSmtng];
If the message the Rec object is sending to its delegate were an optional protocol message, it would instead be sent like this:
if ([[self delegate] respondsToSelector:#selector(optionalProtocolMethod)]) {
[[self delegate] optionalProtocolMethod];
}
The delegate will usually be declared something like:
#property(assign, nonatomic) id<RecDelegate> delegate;
Because it is not retained, in -dealloc, the Rec object only needs to nil it out, not release it:
delegate = nil;
Another way to do something like that is using NSNotificationCenter
in your RecDelegate init method add:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(doSmtng) name:#"someNotification" object:nil];
and in any another place / any class call
[[NSNotificationCenter defaultCenter] postNotificationName:#"someNotification" object:nil];