IOS UITouch传递机制
来源:互联网 发布:mysql数据库设计多对多 编辑:程序博客网 时间:2024/06/05 20:47
1. 首先,
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)
event
和
pointInside:withEvent:
函数是什么关系?
2. 具体到某个例子,UITableView是UIScrollView的子类,那么我们点击一个UITableViewCell的时候,我们是准备上下移动table 还是说要select这个table呢?
3. 如果一个UIScrollView覆盖住一个UIButton,那么我要调用点击那个UIButton 怎么办?
对于第一个问题,hitTest:函数就是判断当前你的手指触摸是不是在当前视图中。如何判断呢? 这里有一大堆话,我是从网上弄下来的,不爱看就直接看下面的图
iOS系统检测到手指触摸(Touch)操作时会将其放入当前活动Application的事件队列,UIApplication会从事件队列中取出触摸事件并传递给key window(当前接收用户事件的窗口)处理,window对象首先会使用hitTest:withEvent:方法寻找此次Touch操作初始点所在的视图(View),即需要将触摸事件传递给其处理的视图,称之为hit-test view。
window对象会在首先在view hierarchy的顶级view上调用hitTest:withEvent:,此方法会在视图层级结构中的每个视图上调用pointInside:withEvent:,如果pointInside:withEvent:返回YES,则继续逐级调用,直到找到touch操作发生的位置,这个视图也就是hit-test view。
hitTest:withEvent:方法的处理流程如下:
首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内;
若返回NO,则hitTest:withEvent:返回nil;
若返回YES,则向当前视图的所有子视图(subviews)发送hitTest:withEvent:消息,所有子视图的遍历顺序是从top到bottom,即从subviews数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕;
若第一次有子视图返回非空对象,则hitTest:withEvent:方法返回此对象,处理结束;
如所有子视图都返回非,则hitTest:withEvent:方法返回自身(self)。
hitTest:withEvent:方法忽略隐藏(hidden=YES)的视图,禁止用户操作(userInteractionEnabled=YES)的视图,以及alpha级别小于0.01(alpha<0.01)的视图。如果一个子视图的区域超过父视图的bound区域(父视图的clipsToBounds 属性为NO,这样超过父视图bound区域的子视图内容也会显示),那么正常情况下对子视图在父视图之外区域的触摸操作不会被识别,因为父视图的pointInside:withEvent:方法会返回NO,这样就不会继续向下遍历子视图了。当然,也可以重写pointInside:withEvent:方法来处理这种情况。
对于每个触摸操作都会有一个UITouch对象,UITouch对象用来表示一个触摸操作,即一个手指在屏幕上按下、移动、离开的整个过程。UITouch对象在触摸操作的过程中在不断变化,所以在使用UITouch对象时,不能直接retain,而需要使用其他手段存储UITouch的内部信息。UITouch对象有一个view属性,表示此触摸操作初始发生所在的视图,即上面检测到的hit-test view,此属性在UITouch的生命周期不再改变,即使触摸操作后续移动到其他视图之上
也就是这个意思:
+----------------------------+
|A |
|+--------+ +------------+ |
||B | |C | |
|| | |+----------+| |
|+--------+ ||D || |
| |+----------+| |
| +------------+ |
+----------------------------+
你的继承图表是这样的,然后你的手指放在D视图上,
那么 ,视图A调用(继承图表最上面的)
hitTest:withEvent:
然后每个视图都会调用
pointInside:withEvent:
A return YES;
B return NO;
C return YES;
D return NO;
凡是返回YES的视图中,最下面的就是了 也就是D, hitTest 视图。
然后对于第二个和第三个问题,
解决方式是这样的,你在任何superView里面重载这个函数就可以了。
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)
event
{
UIView *result = [super hitTest:point withEvent:
event
];
CGPoint buttonPoint = [underButton convertPoint:point fromView:self];
if
([underButton pointInside:buttonPoint withEvent:
event
]) {
return
underButton;
}
return
result;
}
0 0
- IOS UITouch传递机制
- IOS中UIScrollView阻断UITouch事件传递
- UITouch事件处理机制
- IOS开发之UITouch
- IOS开发之UITouch
- iOS-------delegate与UITouch
- iOS控件 ----- UITouch相关
- iOS开发之UITouch
- iOS基础:UITouch
- iOS UITouch、UIEvent
- ios消息传递机制
- IOS消息传递机制
- ios事件传递机制
- iOS事件传递机制
- IOS消息传递机制
- IOS事件传递机制
- UITouch/UIResponder:iOS上触摸事件的视图检测和事件传递
- ios 触摸与手势 UItouch
- 桌足撰诅爪茁篆椎淄座纂诅赚浊揍祖子追
- No suitable driver found for jdbc
- Eclipse 远程调试
- 【TCP/IP 协议】 TCP/IP 基础
- Hive的几种内置服务
- IOS UITouch传递机制
- if语句的举例
- 谆兹赘谞着嘴壮住砖组着酌准啄椎捉仔昨
- IT书籍阅读推荐
- 数据结构——排序算法总结
- session
- xcode下关闭NSLog功能
- 图像的Hougn变换
- cocos2dx3.X项目重写(六)添加不同高度的地图和跳跃优化