从@selector中closures视图控制器而不创build独立的方法

我试图直接从button中取消提交的视图控制器,而不是仅仅为它做一个单独的方法,但我迷失在如何得到这个工作,或者甚至是可能的。

提供的任何帮助表示赞赏!

代码我正在尝试:

[dismissButton addTarget:self action:@selector(dismissViewControllerAnimated:YES completion:NULL) forControlEvents:UIControlEventTouchUpInside]; 

我不想做的事情:

 - (void)dismissThis { [self dismissViewControllerAnimated:YES completion:NULL]; } 

它不会那样工作。 从UIControl的文档addTarget:action:forControlEvents: ::

该动作消息可以可选地按照该顺序包括发送者和事件作为参数。

所以你有三个可能的select器:

 @selector(name) @selector(nameWithParam:) @selector(nameWithParam: otherParam:) 

如果你的select器是@selector(dismissViewControllerAnimated:completion:) ,它将被发送者调用,而不是animation的BOOL和事件,而不是完成处理程序块,这会使应用程序崩溃。

编辑澄清为什么它崩溃: dismissViewControllerAnimated:completion:通过发送copy消息copy完成块。 该事件对象不会实现copy ,你会得到一个NSInvalidArgumentException

苹果的标准API不支持它,但是通过UIControl上的一个类别添加这个function是很容易的。 JTTargetActionBlock添加了这个function。 它也可以作为一个Cocoapod 。

 [button addEventHandler:^(UIButton *sender, UIEvent *event) { [self dismissViewControllerAnimated:YES completion:nil]; } forControlEvent:UIControlEventTouchUpInside]; 

我喜欢处理这个的方式是UIButton并添加一个基于块的操作:

 @interface BlockButton : UIButton @property (nonatomic, copy) void (^onPress)(); @end @implementation BlockButton -(id) initWithFrame:(CGRect)frame { if(self = [super initWithFrame:frame]) { [self addTarget:self action:@selector(pressed:) forControlEvents:UIControlEventTouchUpInside]; } return self; } -(void) pressed:(id)sender { if(self.onPress)self.onPress(); } @end 

然后,而不是

 [dismissButton addTarget:self action:@selector(dismissViewControllerAnimated:YES completion:NULL) forControlEvents:UIControlEventTouchUpInside]; - (void)dismissThis { [self dismissViewControllerAnimated:YES completion:NULL]; } 

您可以使用:

 dismissButton.onPress = ^{ [self dismissViewControllerAnimated:YES completion:NULL]; }; 

我相信你可以适应这个稍微使用UIButton类别,而不是你想要的自定义button类。