Ios 如何从UIView子类调用UIViewController方法

Ios 如何从UIView子类调用UIViewController方法,ios,objective-c,ipad,delegation,Ios,Objective C,Ipad,Delegation,我正在为iPad开发和安装iOS应用程序。我有一个UIView子类,我想从该子类调用ViewController的一个方法。我尝试编写一个委托,但它不起作用。这是一个好的解决方案,还是我必须用另一种方法 Try block,下面是示例: MyView.h @interface MyView: UIView ... @property (nonatomic, copy) void(^myEventCallBack)(id someData); ... @end MyView.m 如何调用块示例

我正在为iPad开发和安装iOS应用程序。我有一个UIView子类,我想从该子类调用ViewController的一个方法。我尝试编写一个委托,但它不起作用。这是一个好的解决方案,还是我必须用另一种方法

Try block,下面是示例:

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);
};

Try block,以下是示例:

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);
};

一般来说,概念上遥远的对象之间的通信是一个棘手的问题,但它是Cocoa编程的核心。从一个实例到另一个实例的引用是至关重要的!我在这里一般讨论这个问题:

这里有一种可能性。如果此UIView实例位于接口中,则其nextResponder是视图控制器,或者它是其nextResponder是视图控制器的superview的子视图。此外,视图层次结构与响应器链平行。因此,只需沿着响应器链一直走到视图控制器

UIResponder* r = someView; // the view instance, living in the interface
while (![r isKindOfClass:[UIViewController class]])
    r = [r nextResponder];
现在r是视图控制器。现在转换到您知道的实际视图控制器的类,您将能够调用该类上的方法:

MyViewController* vc = (MyViewController*)r;
以下是我的书中对响应者链的总结:


然而,还有许多其他的可能性。正如已经有人建议的那样,您可以通过NST建立通信线路;它很难看,但确实有效,部分目的是为了涵盖这种棘手的情况。

一般来说,概念上遥远的对象之间的通信问题是棘手的,但它是Cocoa编程的核心。从一个实例到另一个实例的引用是至关重要的!我在这里一般讨论这个问题:

这里有一种可能性。如果此UIView实例位于接口中,则其nextResponder是视图控制器,或者它是其nextResponder是视图控制器的superview的子视图。此外,视图层次结构与响应器链平行。因此,只需沿着响应器链一直走到视图控制器

UIResponder* r = someView; // the view instance, living in the interface
while (![r isKindOfClass:[UIViewController class]])
    r = [r nextResponder];
现在r是视图控制器。现在转换到您知道的实际视图控制器的类,您将能够调用该类上的方法:

MyViewController* vc = (MyViewController*)r;
以下是我的书中对响应者链的总结:


然而,还有许多其他的可能性。正如已经有人建议的那样,您可以通过NST建立通信线路;这很难看,但确实有效,部分目的是为了涵盖这种棘手的情况。

代理应该有效。现在我可以问一下你想要达到什么目标吗?也许你会更好地子类化UiViewcontroller,你可以发布一些关于如何使用委托的代码。请发布一些代码或类图。让我大胆猜测一下:委托属性为零。如果没有更多信息,很难提出建议。委托模式应该可以工作,但另一种选择是使用NSNotification。当然,有很多方法可以做到这一点。您是否正确地检查了iAction连接?在我的例子中,我可以在子类的方法不匹配UIView类名时使用。不是文件的所有者。委托应该可以工作。现在我可以问一下你想要达到什么目标吗?也许你会更好地子类化UiViewcontroller,你可以发布一些关于如何使用委托的代码。请发布一些代码或类图。让我大胆猜测一下:委托属性为零。如果没有更多信息,很难提出建议。委托模式应该可以工作,但另一种选择是使用NSNotification。当然,有很多方法可以做到这一点。您是否正确地检查了iAction连接?在我的例子中,我可以在子类的方法不匹配UIView类名时使用。不是文件的所有者。不知道为什么会被否决。我经常使用它,所以我已经为它设置了一个视图类别。是的,它不像是黑客或其他什么。nextResponder是视图查看其视图控制器的方式。不知道为什么会被否决。我经常使用它,所以我已经为它设置了一个视图类别。是的,它不像是黑客或其他什么。nextResponder是视图查看其视图控制器的方式。