0%

让UIImageView像UIButton那样点击

#前言
让图片可点击这个需求在项目中经常遇到,一般我会有两种做法。

  • UIImageView + UITapGestureRecognizer
  • UIButton setBackgroundImage

但是最近遇到这样一种需求:

  • 图片可点击
  • 图片数量多
  • 能够获取Image对象

如果还用上面那两种方法的话,感觉有点蛋疼,于是自己就写了一个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。