我们知道UITableView没有像UIButton那样可以通过addTarget方法来监听touch事件,因此在某些场合,特别是在 UITableViewCell中包含UITextField的时候,我们很有可能想通过点击UITableView的其他地方来取消 UITextField的焦点。也许有朋友会说,使用UITapGestureRecognizer手势来取消焦点,这样是可以行得通,但是如果 TextField中有clearButton或者其自定义的Button的时候,手势就会吸收掉事件了,导致按钮无效。
因此,我想到的做法就是重写UITableView的touch相关的方法,然后通过委托的方式提供给外部对象使用。首先定义Delegate:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
@protocol TouchTableViewDelegate <NSObject> @optional - ( void )tableView:(UITableView *)tableView touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - ( void )tableView:(UITableView *)tableView touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; - ( void )tableView:(UITableView *)tableView touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; - ( void )tableView:(UITableView *)tableView touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; @end |
然后UITableView的子类加入一委托对象,并重写所有touch相关方法,如下:
1
2
3
4
5
6
7
8
9
|
@interface TouchTableView : UITableView { @ private id _touchDelegate; } @property (nonatomic,assign) id<TouchTableViewDelegate> touchDelegate; @end |
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
|
@implementation TouchTableView @synthesize touchDelegate = _touchDelegate; - ( void )touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; if ([_touchDelegate conformsToProtocol:@protocol(TouchTableViewDelegate)] && [_touchDelegate respondsToSelector:@selector(tableView:touchesBegan:withEvent:)]) { [_touchDelegate tableView:self touchesBegan:touches withEvent:event]; } } - ( void )touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesCancelled:touches withEvent:event]; if ([_touchDelegate conformsToProtocol:@protocol(TouchTableViewDelegate)] && [_touchDelegate respondsToSelector:@selector(tableView:touchesCancelled:withEvent:)]) { [_touchDelegate tableView:self touchesCancelled:touches withEvent:event]; } } - ( void )touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesEnded:touches withEvent:event]; if ([_touchDelegate conformsToProtocol:@protocol(TouchTableViewDelegate)] && [_touchDelegate respondsToSelector:@selector(tableView:touchesEnded:withEvent:)]) { [_touchDelegate tableView:self touchesEnded:touches withEvent:event]; } } - ( void )touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { [super touchesMoved:touches withEvent:event]; if ([_touchDelegate conformsToProtocol:@protocol(TTWTableViewDelegate)] && [_touchDelegate respondsToSelector:@selector(tableView:touchesMoved:withEvent:)]) { [_touchDelegate tableView:self touchesMoved:touches withEvent:event]; } } @end |
重写touch方法时必须把父类实现方法写上,否则UITableViewCell将无法正常工作。所有的改写工作如上所示,新的TableView类 具有touch事件响应了,使用方法也很简单在原有UITableView的基础上赋予touchDelegate委托即可取到touch事件响应。如 下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
- ( void )loadView { [super loadView]; TouchTableView *tableView = [[TouchTableView alloc]initWithFrame:CGRectMake(0.0, 0.0, 320, 460) style:UITableViewStyleGrouped]; tableView.touchDelegate = self; //相关处理 [self.view addSubview:tableView]; [tableView release]; } - ( void )tableView:(TTWTableView *)tableView touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { //touch结束后的处理 } |