我有一个带有 3 个子 UIViewController 子类的容器视图控制器(添加了 addChildViewController)。我希望我的一个子视图控制器在将某些东西从我的容器视图控制器放到它上面时做某事。我很难理解这种交流应该如何发生。如果我尝试创建一个委托,我会在我的子视图控制器中收到错误,因为我将两个子类相互导入。
2 回答
听起来你在编译你的应用程序时遇到了问题,因为相互之间有相互的 .h 文件importing
,对吧?
编辑:再次阅读您的问题后,我不是 100% 清楚哪个视图控制器需要调用另一个视图控制器。如果我在解决方案中混淆了父视图控制器和子视图控制器的角色,只需切换它们。下面的技术让您可以在任意两个视图控制器(父子、兄弟和兄弟等)之间进行通信。
有很多方法可以处理这个问题。如果您想保留一种delegate
模式,您可以简单地重写标题以避免#import
在 .h 文件之一中出现:
父视图控制器.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"
这应该避免使您的应用程序无法编译的循环依赖。
现在,尽管上述方法有效,但为了清洁起见,我可能会选择另一种解决方案。使用protocol
. 父级可以实现协议,然后子级只需要一个实现协议的委托:
#import "MyProtocol.h"
@interface ParentViewController: UIViewController<MyProtocol> {
}
- (void) doSomething;
在 MyProtocol.h 中:
@protocol MyProtocol
- (void) doSomething;
@end
然后在 ChildViewController.h
#import "MyProtocol.h"
@interface ChildViewController: UIViewController {
@private
id<MyProtocol> delegate;
}
@property (nonatomic, assign) id<MyProtocol> delegate;
在 ChildViewController.m 中:
[delegate doSomething];
或者,您可以完全避免使用委托,并使用 控制器在控制器之间进行通信NSNotificationCenter
,这将它们解耦,并避免编译器循环(双向依赖)。
你就不能去吗:
MyChildViewController *myChildViewController = (MyChildViewController *)[self.childViewControllers objectAtIndex:0];
[myChildViewController doWhatever];
? 这应该让您在数组 childViewControllers 的第一个索引处向子视图控制器发送消息(这是 UIViewController 上的一个属性)。