سؤال

I add UIButton programmatically (self.button is my property UIButton):

self.button = [[UIButton alloc] initWithFrame:CGRectMake(139, 366, 42, 34)];
[self.button addTarget:self action:@selector(buttonPressed:completion:) forControlEvents:UIControlEventTouchUpInside];

I call programmatically to the button target and also I want the framework to invoke the target when the user push the button.

The target selector is:

-(void)buttonPressed:(UIButton*)sender completion:(void (^)())completionBlock;

The second argument is a block.

When I try to introspection/invoke the block I get an exception EXC_BAD_ACCESS (code=2, address=0x0) I know that I try to invoke UITouchesEvent because of the framework target action.

How can I make custom target with completion block?

هل كانت مفيدة؟

المحلول

You can't pass a completion block there, but you can make something like this:

self.button = [[UIButton alloc] initWithFrame:CGRectMake(139, 366, 42, 34)];
[self.button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];

-(void)buttonPressed:(UIButton*)sender {
    [self buttonPressed:sender completion:^{
        //something
    }];
}

-(void)buttonPressed:(UIButton*)sender completion:(void (^)())completionBlock {
    //do something

    //invoke block
    completionBlock();
}

نصائح أخرى

You can't. For the button action, system expect to have a single parameter and that too is the sender(Invoker of the action method) ie the UIButton instance itself. If you want to do anything with a second argument i would suggest you to have a wrapper some thing like

-(void)buttonPressed:(UIButton*)sender
{
 [self customMethodWithcompletion:^{

}];
}

Inside the customMethodWithcompletion you can perform your operations.

A target-action listener for UIKit must have one of the following three signatures:

- (void)action
- (void)action:(id)sender
- (void)action:(id)sender forEvent:(UIEvent *)event

If there is a first parameter, the "sender" control (the control that you are listening to actions for) will be passed to it. If there is furthermore a second parameter, the UIEvent object will be passed to it. You don't have any control over what is passed to the method.

There are many third-party libraries that implement a Block-based API for UIControls that you can find on the Internet. Essentially what they do is attach the completion block as an associative object to the control, and retrieve it in the handling method.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top