iOS开发-UIButton使用block响应点击事件

前言

为什么要给UIButton添加block点击事件,要放弃Action-Target的方式?

首先第一个是因为懒,写Action-Target要比写block多写好多代码,还要想一个好一点的方法名,起名什么的最困难啦。

其次是能最快最直观地看到UIButton要做什么事情。

添加方法

为了兼容性和拓展性,所以使用category给UIButton添加了一个属性和两个Block方法。

#import <UIKit/UIKit.h>

typedef void(^ActionBlock)(UIButton* button);

@interface UIButton (block)

@property (nonatomic, copy) ActionBlock actionBlock;

/**
 button 添加点击block事件

 @param action 点击事件回调
 */
- (void)addAction:(ActionBlock)action;

/**
 button 添加点击block事件

 @param controlEvents 点击的方式
 @param action 点击事件回调
 */
- (void)addControlEvents:(UIControlEvents)controlEvents Action:(ActionBlock)action;

@end

实现代码的逻辑也不复杂:先将传入的block给保存下来,然后给UIButton addTarget一个固定方法,方法中调用block即可。

#import "UIButton+block.h"

#import <objc/runtime.h>

static const char keyActionBlock;

@implementation UIButton (block)

@dynamic actionBlock;

- (void)addAction:(ActionBlock)action
{
    [self addControlEvents:UIControlEventTouchUpInside Action:action];
}

- (void)addControlEvents:(UIControlEvents)controlEvents Action:(ActionBlock)action
{
    if (!action) {
        return;
    }
    objc_setAssociatedObject(self, &keyActionBlock, action, OBJC_ASSOCIATION_COPY_NONATOMIC);
    [self addTarget:self action:@selector(buttonTarget) forControlEvents:controlEvents];
}

- (void)buttonTarget
{
    ActionBlock action = (ActionBlock)objc_getAssociatedObject(self, &keyActionBlock);
    if (action){
        action(self);
    }
}

- (void)setActionBlock:(ActionBlock)actionBlock
{
    [self addAction:actionBlock];
}

-(ActionBlock)actionBlock
{
    return objc_getAssociatedObject(self, &keyActionBlock);
}

@end

使用方式

UIButton *btn = [[UIButton alloc]init];
btn.actionBlock = ^(UIButton *btn) {
    NSLog(@"Button Action");
};
[btn addAction:^(UIButton *button) {
    NSLog(@"Button Action");
}];
[btn addControlEvents:UIControlEventTouchUpInside Action:^(UIButton *button) {
    NSLog(@"Button Action");
}];

缺点

block点击事件的缺点是无法添加多个事件,以及block的通病容易造成循环引用,实际使用上来说基本都会循环引用。

猜你喜欢

转载自blog.csdn.net/qq_36557133/article/details/102036080