iOS小知识点06

今天在上看到一篇大神写的以block的形式自定义返回按钮动作的按钮,然后自己尝试了一些想法,以下是在借鉴了大神的文章后,自己想的三种方法来实现不调用按钮的addTarget方法改用block的形式降低代码的分散度。

方法一:通过继承UIButton自定义CustomButton

CustomButton.h 文件中的代码:

#import 
// 定义block
typedef void(^CompletionHandler)(void);

@interface CustomButton : UIButton

// 用此方法代替原有的addTarget方法
- (void)addActionForControlEvents:(UIControlEvents)controlEvents respond:(CompletionHandler)completion;

@end

CustomButton.m 文件中的代码:

#import "CustomButton.h"

@interface CustomButton()

@property (nonatomic, copy) CompletionHandler completion;

@end

@implementation CustomButton

- (void)addActionForControlEvents:(UIControlEvents)controlEvents respond:(CompletionHandler)completion {
    [self addTarget:self action:@selector(didClickButton) forControlEvents:controlEvents];
    self.completion = completion;
}
 // 点击button时
- (void)didClickButton {
    self.completion();
}

@end

方法二:通过分类的方式并使用运行时关联对象

UIButton+Category1.h文件中的代码:

#import 

typedef void(^CompletionHandler)(void);

@interface UIButton (Category1)

@property (nonatomic, copy) CompletionHandler completion;

- (void)addActionForControlEvents:(UIControlEvents)controlEvents respond:(CompletionHandler)completion;

@end

UIButton+Category1.m文件中的代码:

#import "UIButton+Category1.h"
#import 

static NSString *completionKey = @"completionKey";

@implementation UIButton (Category1)
//通过运行时关联引用(见iOS小知识点02)
//以前还以为只是关联NSString那样的属性,现在想想,block块也是一种类型,既然是类型,就可以定义为 属性,那么应该是可以用运行时关联的吧。
- (void)setCompletion:(CompletionHandler)completion {
   objc_setAssociatedObject(self, &completionKey, completion, OBJC_ASSOCIATION_COPY);
}

- (CompletionHandler)completion {
   return objc_getAssociatedObject(self, &completionKey);
}

- (void)addActionForControlEvents:(UIControlEvents)controlEvents respond:(CompletionHandler)completion {
    [self addTarget:self action:@selector(didClickButton) forControlEvents:controlEvents];
    self.completion = completion;
}

- (void)didClickButton {
    self.completion();
}

@end

方法三:通过分类的方式并使用运行时关联对象(缩减版)

UIButton+Category2.h文件中的代码:

#import 

@interface UIButton (Category2)

- (void)addActionForControlEvents:(UIControlEvents)controlEvents respond:(void (^)())completion;

@end

UIButton+Category2.m文件中的代码:

#import "UIButton+Category2.h"
#import 

static NSString *completionKey = @"completionKey";

@implementation UIButton (Category2)

- (void)addActionForControlEvents:(UIControlEvents)controlEvents respond:(void (^)())completion {
    [self addTarget:self action:@selector(didClickButton) forControlEvents:controlEvents];
    objc_setAssociatedObject(self, &completionKey, completion, OBJC_ASSOCIATION_COPY);
}

- (void)didClickButton {
    void (^block)() = objc_getAssociatedObject(self, &completionKey);
    block();
}

@end

原理和方法二差不多,只是减少了一些代码量(本人较懒)。

在viewDidLoad中验证可行性

UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
[button setBackgroundColor:[UIColor blueColor]];
[button addActionForControlEvents:UIControlEventTouchUpInside respond:^{
    NSLog(@"按钮被点击了");
}];
[self.view addSubview:button];

你可能感兴趣的:(iOS小知识点06)