0

I've a custom view subclass with UIView, in it, I've two buttons with an action, now I want to learn something good, and I don't want to implement a delegate to know which button tapped from other class.

I'm showing my custom view with this method,

CustomView *view = [[CustomView alloc] init];
[view show];

This will show my custom view, with two buttons inside (please assume everything is working fine, I only want to implement block to know which button have been tapped). ^_^

What I've tried for block,

- (void) showViewWithCompletionBlock:(void(^)(CustomViewType type))completion;

and yes, I would able to write like this,

CustomView *view = [[CustomView alloc] init];
[view showViewWithCompletionBlock:^(CustomViewType type) {

}];

but now here's the trouble, I don't know how to call this block (or how I can return CustomViewType) when button tap?

Those two buttons action is like this,

- (void) someAction:(UIButton *)sender {
     //sender.tag is a CustomViewType which user choose
}

For a note, CustomViewType is an enum like this,

typedef enum {
    CustomViewTypeOption1,
    CustomViewTypeOption2,
}CustomViewType;
0

4 Answers 4

1

It's easier to deal with blocks using a typedef:

typedef void(^CustomViewCompletionBlock)(CustomViewType type);

(same thing goes for function pointers).

Now store this block in the custom view, using a private category in the .m file:

@interface CustomView () {
    CustomViewCompletionBlock _completionBlock;
}
@end

@implementation CustomView
...
@end

Do whatever is necessary to display the view and store the completion block:

- (void)showViewWithCompletionBlock:(CustomViewCompletionBlock)completion
{
    // Do whatever it takes to "display" the view
    ...
    _completionBlock = completion;
}

and then call the completion block as-and-when:

- (IBAction)button1Action:(id)sender
{
    // Whatever else this method does
    ...
    if (_completionBlock) {
        _completionBlock(CustomViewTypeOption1);
    }
}

- (IBAction)button2Action:(id)sender
{
    // Whatever else this method does
    ...
    if (_completionBlock) {
        _completionBlock(CustomViewTypeOption2);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

Please try below code. when you call compilation . take reference of that compilation and when you want to call that block just use that reference.

in .h

typedef enum {
CustomViewTypeOption1,
CustomViewTypeOption2,
}CustomViewType;

typedef void(^CustomViewCompletionBlock)(CustomViewType type);

@interface CustomView : UIView
{
    CustomViewCompletionBlock custVTypeBlock;
}
- (void)showViewWithCompletionBlock:(CustomViewCompletionBlock)completion;

@end

in .m

- (void)showViewWithCompletionBlock:(CustomViewCompletionBlock)completion
{
    custVTypeBlock = completion;
    //i'm calling this for sample.
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self someAction:nil];
    });
}
- (void) someAction:(UIButton *)sender {
    //sender.tag is a CustomViewType which user choose
    // call your compilation with your enum.
    if(custVTypeBlock)
        custVTypeBlock(0);
}

Maybe this will help you.

Comments

0

Try https://github.com/lavoy/ALActionBlocks

It supports UIControl (UIButton), UIBarButtonItem, and UIGestureRecognizer. It is also supported using CocoaPods.

Comments

0

Calling a block type is just like calling a C method. If you your block variable name is, say, myBlock and if it returns a CustomType, then this will work for you:

CustomType blockReturnedCustomType = myBlock();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.