Reputation: 4562
I have a container view controller with 3 child UIViewController subclasses (added with addChildViewController). I want one of my child view controllers to do something when something is dropped from my container view controller onto it. I'm having trouble grasping how this communication should happen. If I try making a delegate, I get an error in my child view controller because I would both subclasses to import each other.
Upvotes: 0
Views: 3476
Reputation: 31045
It sounds like you're having a problem compiling your app because of mutual .h files importing
each other, right?
Edit: upon reading your question again, I'm not 100% clear on which view controller needs to call which other one. If I mixed up the roles of parent and child view controller in my solution, just switch them. The techniques below let you communicate between any two view controllers (parent and child, sibling and sibling, etc.)
There's a number of ways to handle this. If you want to stay with a delegate
pattern, you could simply rewrite the header to avoid the #import
in one of the .h files:
ParentViewController.h:
#import "ChildViewController.h"
@interface ParentViewController: UIViewController {
@private
ChildViewController* childVc;
}
- (void) doSomething;
ChildViewController.h
@class ParentViewController; // NOT #import!
@interface ChildViewController: UIViewController {
@private
ParentViewController* parentVc;
}
ChildViewController.m
#import "ParentViewController.h"
This should avoid the circular dependency that keeps your app from compiling.
Now, although the above works, I might choose another solution, for the sake of cleanliness. Use a protocol
. The parent can implement the protocol and then the child only needs to have a delegate that implements the protocol:
#import "MyProtocol.h"
@interface ParentViewController: UIViewController<MyProtocol> {
}
- (void) doSomething;
In MyProtocol.h:
@protocol MyProtocol
- (void) doSomething;
@end
Then in ChildViewController.h
#import "MyProtocol.h"
@interface ChildViewController: UIViewController {
@private
id<MyProtocol> delegate;
}
@property (nonatomic, assign) id<MyProtocol> delegate;
And in ChildViewController.m:
[delegate doSomething];
Or, you could avoid using delegates altogether, and communicate between the controllers using NSNotificationCenter
, which decouples them a bit, and avoids your compiler circularity (bidirectional dependency).
Here are the Apple docs on NSNotificationCenter
Upvotes: 5
Reputation:
Couldn't you just go:
MyChildViewController *myChildViewController = (MyChildViewController *)[self.childViewControllers objectAtIndex:0];
[myChildViewController doWhatever];
? That should let you message the child view controller at the first index of the array childViewControllers (which is a property on UIViewController).
Upvotes: 2