Reputation: 19
I have two uiviewcontroller
: MainViewController
and SecondaryViewControlle
. In MainViewController
I do:
[self.view addSubView:SecondaryViewControlle.view];
The SecondaryViewController
is a button by pressing the function to be performed by a MainViewController
. How to do?
Upvotes: 0
Views: 67
Reputation: 1191
Option A
It's quicker, and easier, but lacks the maintainability, since there is no contract stating that SecondaryViewController needs to bother calling anything, and self.parentViewController could be any UIViewController.
Option B
The delegate pattern; this is my preference, it's obvious what's happening, what's required, and there's a nice solid contract that states, if you want to initialise me, give me a delegate.
Option C
If SecondaryViewController has to notify multiple objects, it would be quick to use the NSNotificationCenter, but as with Option A, there's no contract, should you need to notify many objects, you would need to remember to listen for notifications on those objects - since this is not the question, I won't go into detail, it's just here for the information
Option A
Within MainViewController.m, do something like so:
SecondaryViewController *viewcontroller = [[SecondaryViewController alloc] initWithNibName:@"SecondaryView" bundle:nil];
[self addChildViewController:viewcontroller];
//set viewcontroller.view frame
[self.view addSubview:viewcontroller.view];
[viewcontroller didMoveToParentViewController:self];
Inside MainViewController.h
-(void) performButtonClickAction;
Inside MainViewController.m:
-(void) performButtonClickAction {
//Do something constructive
}
and then inside the SecondaryViewController.m:
-(IBAction) buttonPressed:(id) sender {
[self.parentViewController performButtonClickAction];
}
Option B
Inside SecondaryViewController.h
@protocol SecondaryViewControllerDelegate <NSObject>
-(void) eventAFromViewController:(UIViewController *) viewController;
-(void) eventBFromViewController:(UIViewController *) viewController;
@end
@interface SecondaryViewController : UIViewController {
id<SecondaryViewControllerDelegate> delegate;
}
@property (assign, nonatomic) id<SecondaryViewControllerDelegate> delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil delegate:(id<SecondaryViewControllerDelegate>) theDelegate;
@end
Inside SecondaryViewController.m @synthesize delegate = _delegate;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil delegate:(id<SecondaryViewControllerDelegate>) theDelegate
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.delegate = theDelegate;
}
return self;
}
-(IBAction) buttonPressed:(id) sender {
if( self.delegate != nil ) {
[_delegate eventAFromViewController:self];
}
else {
//No delegate
}
}
Upvotes: 0
Reputation: 89509
You'd start by defining a protocol in your SecondViewControlle.h file, something like:
@protocol SecondViewControlleDelegate
- (void) doSomething
@end
You would also need to add a "delegate
" ivar to your SecondViewControlle .h file. It would be the delegate line:
@interface SecondViewControlle : UIViewController
...
...
...
@property (nonatomic, assign) id delegate; // all you need to do is add this line inside your interface declarations
...
...
...
@end
Then, when you create / instantiate your SecondaryViewControlle from your MainViewController, make certain to add the MainViewController as the delegate like so:
SecondaryViewControlle.delegate = self;
[self.view addSubView:SecondaryViewControlle.view];
Now the "delegate
" of your SecondaryViewControlle view controller points back to your MainViewController.
And when the button is pressed, you can simply do something like:
- (IBAction) buttonIsPressed: (id) sender
{
[delegate doSomething];
}
Now, I need to give you some advice here.
1 ) DO NOT use the class names as object names. Instead of having an object named "SecondViewControlle
", name it something different (and start it with a lower case, which is Objective-C convention), something like "moreDetailVC
".
2) I've told you how to do this with a delegate pattern, but this may not be the most appropriate way to do whatever it is that you're trying to do. After all, the MainViewController object (which should be renamed mainVC
to differentiate the object from the class) is not on screen or visible so maybe there's a better place to put the functionality?
Upvotes: 1