Reputation: 930
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
Upvotes: 0
Views: 2039
Reputation: 22946
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
{
...
}
ViewDelegate
/ViewControllerDelegate
. Just define the delegate in header of class it belongs to: HelpViewController.n
in this case.switchToggled:
in the real class MainViewController
, and not in the extra/unnecessary class ViewDelegate
.MainViewController
in HelpViewController
you create such a dependency. This is not necessary as I show, and is wrong design. MainViewController
already needed HelpViewController
in order to show it, and now they need each other the other way around for sending the event.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).Upvotes: 1
Reputation: 1848
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 HelpViewController
then 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.
Upvotes: 0