让UITableView响应touch事件

我们知道UITableView没有像UIButton那样可以通过addTarget方法来监听touch事件,因此在某些场合,特别是在UITableViewCell中包含UITextField的时候,我们很有可能想通过点击UITableView的其他地方来取消UITextField的焦点。也许有朋友会说,使用UITapGestureRecognizer手势来取消焦点,这样是可以行得通,但是如果TextField中有clearButton或者其自定义的Button的时候,手势就会吸收掉事件了,导致按钮无效。

因此,我想到的做法就是重写UITableView的touch相关的方法,然后通过委托的方式提供给外部对象使用。首先定义Delegate:

01 @protocol
TouchTableViewDelegate <NSObject>
02  
03 @optional
04  
05 -
(
void)tableView:(UITableView
*)tableView
06      touchesBegan:(NSSet
*)touches
07         withEvent:(UIEvent
*)event;
08  
09 -
(
void)tableView:(UITableView
*)tableView
10  touchesCancelled:(NSSet
*)touches
11         withEvent:(UIEvent
*)event;
12  
13 -
(
void)tableView:(UITableView
*)tableView
14      touchesEnded:(NSSet
*)touches
15         withEvent:(UIEvent
*)event;
16  
17 -
(
void)tableView:(UITableView
*)tableView
18      touchesMoved:(NSSet
*)touches
19         withEvent:(UIEvent
*)event;
20  
21  
22 @end

然后UITableView的子类加入一委托对象,并重写所有touch相关方法,如下:

1 @interface 
TouchTableView : UITableView
2 {
3 @private
4     id
_touchDelegate;
5 }
6  
7 @property
(nonatomic,assign) id<TouchTableViewDelegate> touchDelegate;
8  
9 @end
01 @implementation
TouchTableView
02  
03 @synthesize
touchDelegate = _touchDelegate;
04  
05 -
(
void)touchesBegan:(NSSet
*)touches withEvent:(UIEvent *)event
06 {
07     [super
touchesBegan:touches withEvent:event];
08      
09     if ([_touchDelegate
conformsToProtocol:@protocol(TouchTableViewDelegate)] &&
10         [_touchDelegate
respondsToSelector:@selector(tableView:touchesBegan:withEvent:)])
11     {
12         [_touchDelegate
tableView:self touchesBegan:touches withEvent:event];
13     }
14 }
15  
16 -
(
void)touchesCancelled:(NSSet
*)touches withEvent:(UIEvent *)event
17 {
18     [super
touchesCancelled:touches withEvent:event];
19      
20     if ([_touchDelegate
conformsToProtocol:@protocol(TouchTableViewDelegate)] &&
21         [_touchDelegate
respondsToSelector:@selector(tableView:touchesCancelled:withEvent:)])
22     {
23         [_touchDelegate
tableView:self touchesCancelled:touches withEvent:event];
24     }
25 }
26  
27 -
(
void)touchesEnded:(NSSet
*)touches withEvent:(UIEvent *)event
28 {
29     [super
touchesEnded:touches withEvent:event];
30      
31     if ([_touchDelegate
conformsToProtocol:@protocol(TouchTableViewDelegate)] &&
32         [_touchDelegate
respondsToSelector:@selector(tableView:touchesEnded:withEvent:)])
33     {
34         [_touchDelegate
tableView:self touchesEnded:touches withEvent:event];
35     }
36 }
37  
38 -
(
void)touchesMoved:(NSSet
*)touches withEvent:(UIEvent *)event
39 {
40     [super
touchesMoved:touches withEvent:event];
41      
42     if ([_touchDelegate
conformsToProtocol:@protocol(TTWTableViewDelegate)] &&
43         [_touchDelegate
respondsToSelector:@selector(tableView:touchesMoved:withEvent:)])
44     {
45         [_touchDelegate
tableView:self touchesMoved:touches withEvent:event];
46     }
47 }
48  
49 @end

重写touch方法时必须把父类实现方法写上,否则UITableViewCell将无法正常工作。所有的改写工作如上所示,新的TableView类具有touch事件响应了,使用方法也很简单在原有UITableView的基础上赋予touchDelegate委托即可取到touch事件响应。如下:

01 -
(
void)loadView
02 {
03     [super
loadView];
04     TouchTableView
*tableView = [[TouchTableView alloc]initWithFrame:CGRectMake(0.0, 0.0, 320, 460)   style:UITableViewStyleGrouped];
05     tableView.touchDelegate
= self;
06     //相关处理
07     [self.view
addSubview:tableView];
08     [tableView
release];
09 }
10  
11  
12 -
(
void)tableView:(TTWTableView
*)tableView
13      touchesEnded:(NSSet
*)touches
14         withEvent:(UIEvent
*)event
15 {
16     //touch结束后的处理
17 }

时间: 2024-08-09 22:01:22

让UITableView响应touch事件的相关文章

UIScrollView无法响应touch事件的解决方法

用过UIScrollView的都会发现UIScrollView不会响应touch事件,这样就无法在touches相关的方法中做一些事情了,比如收回键盘等等.其实写个categroy就可以解决这个问题了. 具体实现如下: @implementation UIScrollView (UITouchEvent) - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [[self nextResponder] touches

UIScrollView不能响应touch事件的解决办法

UIScrollView本身事是不支持touch的,我们可以给她添加拓展 #import "UIScrollView+util.h" @implementation UIScrollView (util) -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ [[self nextResponder] touchesBegan:touches withEvent:event];

CCLayer在Touch事件(Standard Touch Delegate和Targeted Touch Delegate)

在做练习,触摸故障,看到源代码,以了解下触摸事件. 练习操作:直CClayer子类init在 this->setTouchEnabled(true); 事件处理方法覆盖 virtual bool ccTouchBegan(CCTouch* touch, CCEvent* event); virtual void ccTouchMoved(CCTouch* touch, CCEvent* event); virtual void ccTouchEnded(CCTouch* touch, CCEve

cocos creator Touch事件应用(触控选择多个子节点)

最近参与了cocos creator的研究,开发小游戏,结果被一个事件坑得不行不行的.现在终于解决了,分享给大家. 原理 1.触控事件是针对节点的 2.触控事件的冒泡,是直接关系冒泡,父子可以,孙子不行,就是不能隔代冒泡 3.父节点不响应触控事件,肯定是被孩子节点遮挡了,只要孩子节点也监听一下事件,父节点就可以响应了 4.触控位置是绝对坐标,相对于整个canvas,节点位置相对于父节点,相对位置可以与绝对坐标相互转化 5.节点是否被触控到,touch start事件可以肯定被触摸到,但是一个节点

Android OpenGL ES绘图教程之六 :响应触摸事件

使对象根据预设的程序进行运动,比如旋转三角形,可以吸引人的注意力.但是如果你想让用户同你的OpenGL ES图形进行交互会怎么样呢?使你的OpenGL ES应用程序触摸互动的关键是要扩展GLSurfaceView,复写onTouchEvent()方法,来监听touch事件.本教程展示了,如何监听透出事件,让用户旋转一个OpenGL ES对象. 1.   设置一个Touch Listener 为了使你的OpenGL ES应用响应touch事件,你必须在GLSurfaceView类中实现OnTouc

【Android 1.6】View和ViewGroup的touch事件分析和总结

ENV: android 1.6 目前Android版本已经到了7.0(nougat)了,Android 随着版本升级,touch事件的源码也在跟随着系统的升级而写得越来越复杂,加入了很多旁枝末节,这些旁枝末节,对于分析流程是一种干扰:由于Android的版本升级是向下兼容的,万变不离其宗,研究Android早期的版本,可以更容易理解touch事件的分发,本篇以Android1.6版本的源码进行讲解,由简及繁,理解了早期的源码,再进入高版本的研究也会更容易许多. 前言: View事件的派发其实非

uitableview的空白处不能响应 touchesbegan 事件

现在的uitableview 的上面  响应不了     touchesbegan 事件   可能算是苹果的一个bug吧,不知道以后会不会改变 今天试了好久  都不行  最后  写了个字类  继承自  tableview 结果  可以响应事件了, 但是  上面的cell  也跟着响应这个事件, 真是坑爹啊

解决小米系统下ViewPager、ScrollView内嵌套WebView时,Touch事件不响应的问题

前言:一直拿原生android4.4的Nexus5测试,结果装到老大的小米上,出了bug.安卓的兼容性问题真是....难以形容. Bug详细描述:本人用webview运行JS Goole地图,单独使用该webview时一切正常,而当放在scrollview和viewpager下,小米手机上便无法移动地图,其他手机是没问题的. 解决方案: 一.ScrollView内嵌套WebView 作为一个新手,我简单的检查了viewpager和scrollview的三个函数(dispatchTouchEven

cocos2d-x中关于touch事件的响应

原作者:有缘人  来源:新浪微博 地址:http://blog.sina.com.cn/s/blog_6ac2c7260102vvdu.html 一.touch事件响应分为单点触摸响应和多点触摸响应. 单点触摸响应需要重载的方法: virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent); virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent); virtual void