我正在为iPad开发iOS应用程序。我有一个UIView子类,我想从该子类调用ViewController的方法。我试图编写一个委托代码,但它不起作用。这是一个很好的解决方案还是我必须以另一种方式做到这一点?
答案 0 :(得分:3)
尝试阻止,这是示例:
MyView.h
@interface MyView: UIView
...
@property (nonatomic, copy) void(^myEventCallBack)(id someData);
...
@end
MyView.m (如何调用块样本)
...
- (IBAction)buttonTapped:(UIButton *)sender {
if (self.myEventCallback) {
self.myEventCallback(self.someImportantData);
}
}
...
你在UIViewController中的:
self.myView = [[MyView alloc] initWithFrame:someFrame];
// THIS IS VERY IMPORTANT, USE __weak COPY OF YOUR UIViewController OBJECT (owner of object which contains block) INSIDE BLOCK TO PREVENT RETAIN CIRCLE, CAUSE BLOCK RETAINS ITS CONTENT
__weak MyViewController *self_ = self;
self.myView.myEventCallback = ^(id someData){
[self_ doSomeProcessingWithData:someData];
};
也可以使用块与返回值,示例:
@property (nonatomic, copy) BOOL(^shouldStartProcessing)(void);
self.myView.myEventCallback = ^BOOL{
return (self_.state == MyViewControllerStateReady);
};
答案 1 :(得分:1)
一般来说,概念上“远程”对象之间的通信问题很棘手,但它是Cocoa编程的核心。从一个实例到另一个实例的引用至关重要!我在这里一般性地讨论这个问题:
http://www.apeth.com/iOSBook/ch13.html#_instance_visibility
这是一种可能性。如果此UIView实例位于接口中,则其nextResponder
是视图控制器,或者是nextResponder
是视图控制器的超级视图的子视图。此外,视图层次结构与响应者链平行。因此,只需走上响应链,直到您进入视图控制器。
UIResponder* r = someView; // the view instance, living in the interface
while (![r isKindOfClass:[UIViewController class]])
r = [r nextResponder];
现在r
是视图控制器。现在转换为您所知道的实际视图控制器的类,您将能够在其上调用方法:
MyViewController* vc = (MyViewController*)r;
这是我的书对响应者链的总结:
http://www.apeth.com/iOSBook/ch11.html#_the_responder_chain
然而,还有许多其他可能性。正如有人已经建议的那样,你可以通过NSNotification(shoutcasting)建立通信线路;这很丑陋,但确实有效,而且部分原因只是为了掩盖这种棘手的情况。