#前言
让图片可点击这个需求在项目中经常遇到,一般我会有两种做法。
- UIImageView + UITapGestureRecognizer
- UIButton setBackgroundImage
但是最近遇到这样一种需求:
如果还用上面那两种方法的话,感觉有点蛋疼,于是自己就写了一个UIImageView的子类。
#原理
UIImageView -> UIView -> UIResponder -> NSObject. 继承自UIResponder!那UIImageView响应事件就好办了。在UIResponder头文件中,可以看到响应手势的四个函数
1 2 3 4
| - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
|
那么我可以在Began、Ended、Cancelled这三个函数中想办法:
- 在Began方法中,添加一层模糊遮罩(类似于点击button时的效果)
- 在Ended方法中,取消模糊遮罩,并且让它响应相应的方法
- 在Cancelled方法中,取消模糊遮罩
如何在Ended方法中,如何响应相应的方法呢?我可以采取类似于代理的方法,在头文件暴露一个SEL类型(响应方法)和一个id类型(响应方法的持有对象)的属性,创建该对象的时候赋值。
#代码
h文件
1 2
| @property (nonatomic,assign) id delegate; //回调对象 @property (nonatomic,assign) SEL method; //回调方法
|
m文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.userInteractionEnabled = YES; } return self; }
/** * 实现点击高亮 * * @param touches touches description * @param event event description */ -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { UIView *maskView = [self viewWithTag:viewTag]; if (!maskView) { maskView = [[UIView alloc]initWithFrame:self.bounds]; maskView.backgroundColor = [UIColor whiteColor]; maskView.alpha = 0.25; maskView.tag = viewTag; [self addSubview:maskView]; }else{ maskView.hidden = NO; } }
/** * 重载touch方法 * * @param touches touches description * @param event event description */ -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UIView *maskView = [self viewWithTag:viewTag]; if(maskView){ maskView.hidden=YES; } if([self.delegate respondsToSelector:self.method]){ SuppressPerformSelectorLeakWarning([self.delegate performSelector:self.method withObject:self]); }else{ NSLog(@"回调方法没有实现%@",NSStringFromSelector(self.method)); } }
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { UIView *maskView = [self viewWithTag:viewTag]; if(maskView){ maskView.hidden=YES; } }
|
项目链接: https://github.com/JoakimLiu/FMClickedImageView
#总结
这个方法比较简单,还可以在该子类中添加其他属性、方法,既然UIImageView能用,那么那些继承至UIResponder的其他控件(没有点击响应事件)也能用该方法,比如UILabel。