说一下需求:有一排UIVIew通过点击不同的UIView来回调不同的控制器。
思路:使用runtime机制,为UIView添加一个分类,里面添加手势,使用block回调。
下面看具体源码:
.h文件:
#import <UIKit/UIKit.h>
@interface UIView (Events)
-(void)addClickedBlock:(void(^)(id obj))tapAction;
@end
.m文件:
#import "UIView+Events.h"
#import <objc/runtime.h>
@interface UIView()
@property void(^clickedAction)(id);
@end
@implementation UIView (Events)
- (void)addClickedBlock:(void(^)(id obj))clickedAction{
self.clickedAction = clickedAction;
// hy:先判断当前是否有交互事件,如果没有的话。。。所有gesture的交互事件都会被添加进gestureRecognizers中
if (![self gestureRecognizers]) {
self.userInteractionEnabled = YES;
// hy:添加单击事件
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
[self addGestureRecognizer:tap];
}
}
//set
- (void)setClickedAction:(void (^)(id))clickedAction{
//使用键和关联策略为给定对象设置关联值
//1.关联的源对象
//2.关联的键
//3.设置值(值为get方法)
//4.指定赋值原子对象,并不以原子操作
objc_setAssociatedObject(self, @"AddClickedEvent", clickedAction, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
//get
- (void (^)(id))clickedAction{
return objc_getAssociatedObject(self, @"AddClickedEvent");
}
- (void)tap{
if (self.clickedAction) {
self.clickedAction(self);
}
}
@end
使用方法:
UIView *oneView=[UIView new];
oneView.tag=0;
oneView.userInteractionEnabled=YES;
[oneView addClickedBlock:^(id obj) {
if (_viewAction!=nil) {
self.viewAction(0);
}
}];//类别中的方法
[oneView addSubview:self.addressImage];
[oneView addSubview:self.addressLab];
[self addSubview:oneView];
注意上面的addClickBlock块中我使用了自己另外写的Block,好几个UIView使用这一个Block,参数就是自己写的tag标识。