美文网首页
【小tips】给UIBarButtonItem添加点击事件响应B

【小tips】给UIBarButtonItem添加点击事件响应B

作者: FKSky | 来源:发表于2019-02-26 10:56 被阅读0次

UIBarButtonItem的原生的初始化方法只有使用Target Action来绑定事件响应,大部分时候都没问题,但是偶尔有需求如果能用block来处理它的事件响应就更方便了,看过网上一些人会对UIBarButtonItem或者UIButton添加一个父类来做封装,个人觉得不太友好,以后每次使用都要记得用那个新的类。这里给出一个个人觉得比较方便,代码也比较少的写法,就是使用Category分类来给原生的UIBarButtonItem进行扩展。

主要就用到两个点的知识,一个是Category,一个是runtime
其中runtime主要也就用到两个很常用的方法
动态给对象绑定属性:objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,
id _Nullable value, objc_AssociationPolicy policy)
获取对象的绑定属性objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key)
我们主要用以上两个方法来存取block就行了,如果对runtime不了解的可以去搜一搜,别人写的太多了,这里就不做介绍。

然后创建UIBarButtonItem的分类UIBarButtonItem+Block.h和UIBarButtonItem+Block.m文件,代码如下:

UIBarButtonItem+Block.h

#import <UIKit/UIKit.h>

@interface UIBarButtonItem (Block)

//就用这个方法给对象添加一个block的响应
- (void)bindClickHandlerBlock:(dispatch_block_t)block;

@end

UIBarButtonItem+Block.m

#import "UIBarButtonItem+Block.h"
//引入runtime库
#import <objc/runtime.h>

@implementation UIBarButtonItem (Block)
//用于动态绑定对象的key
static char targetClosureKey;

#pragma mark - public
- (void)bindClickHandlerBlock:(dispatch_block_t)block
{
  //绑定block之前先将可能在初始化时候添加的target action替换成我们自己的
  //这样这个按钮点击的时候就会触发我们这个分类里的activeAction方法
  self.target = self;
  self.action = @selector(activeAction);
  
  //将传入的block对象跟我们的key绑定起来(可以理解为将block存入这个对象的叫做targetClosureKey的属性里
  //最后那个参数OBJC_ASSOCIATION_COPY_NONATOMIC表示我们用copy的策略来赋值)
  objc_setAssociatedObject(self, &targetClosureKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

#pragma mark - private
- (void)activeAction
{
  //按钮点击了会触发此方法,我们就读取之前绑定的block对象
  dispatch_block_t handler = objc_getAssociatedObject(self, &targetClosureKey);
  //如果有就调用它
  if (handler) {
    handler();
  }
}

@end



是不是很简单?下面就是看如何使用了

//在需要用的地方导入分类头文件
#import "UIBarButtonItem+Block.h"

 //跟平常一样,以前你的UIBarButtonItem怎么初始化,现在还是怎么初始化,这就是使用Category比套一个父类优秀的地方了。
 //系统的初始化方法里的target和action填nil就可以了,反正之后也会被我们的分类修改了。
 UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"image"] style:UIBarButtonItemStylePlain target:nil action:nil];
 //对着这个新的 UIBarButtonItem对象调用我们上面写的分类方法,就能给他绑定点击响应block回调了。
 [item bindClickHandlerBlock:^{
    NSLog("click!!!");
  }];

结语:
1.记得组合(category)要优于继承(添加父类)。
2.偶尔使用runtime可以简化代码,但是不能滥用,能力越大责任越大。

相关文章

网友评论

      本文标题:【小tips】给UIBarButtonItem添加点击事件响应B

      本文链接:https://www.haomeiwen.com/subject/dsnoyqtx.html