写点什么

iOS touch 事件点的获取

用户头像
teoking
关注
发布于: 2020 年 10 月 26 日

最近实现了这样一个需求:当点击一个全屏的 modal view 时,这个事件同时要“转发”给 modal view 下面一层中的 action view。

分解为技术需求就是获取到 modal view 的 touch 点,然后交给 action view 去处理。

下面是我实现过程中的两个方案。


实现一:touchesBegan:withEvent:

使用 UIResponder 的touchesBegan:withEvent:来获取 touch 点坐标,然后转交给 action view 的持有者,来触发对应的 action。


具体实现步骤:

  1. 在 ModalView 中加入对 touch 事件的监测

// 由于ModalButton是全屏的,屏幕上绝大部分位置的touch事件都会被如下回调监测到- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{    // 计算出touch事件对应的点    UITouch *aTouch = [touches anyObject];    CGPoint point = [aTouch locationInView:self];    // point.x and point.y have the coordinates of the touch    // 将该点记录下来,便于后续通过delegate或其它方式通知给controller    self.lastTapPoint = point;}
// 如果只是想拦截touch手势点,而不是pan手势点,在这里要将位置点清空- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ // If pan or move, clear point self.lastTapPoint = CGPointZero;}
复制代码
  1. 将 lastTapPoint 通知给 ActionView 或其持有者

  2. 判断该点是否在 ActionView 的 frame 内

// 如下代码示例中,我需要判断point是否在imageView或label内- (BOOL)checkPointInsideMenuItem:(UIView *)container point:(CGPoint)point {    UIView *actionView1 = ...;    // 注意:这里一定要对point做下坐标系转换    CGPoint aPoint = [container convertPoint:point toView:actionView1];    if (imageView && [actionView1 pointInside:aPoint withEvent:nil]) {        return YES;    }    UIView *actionView2 = ...;    aPoint = [container convertPoint:point toView:actionView2];    if (actionView2 && [actionView2 pointInside:aPoint withEvent:nil]) {        return YES;    }    return NO;}
复制代码

UIView 的convertPoint:toView: 可以很方便的将当前 view 中的点,转换为目标 view 坐标系中的点。


测试结果:

该实现存在明显 bug:有很大概率touchesBegan:withEvent:不能被系统回调,尝试了不少设置,也不能解决。虽然回调不能触发,但是 ModalView 的 tap gesture 却可以触发到 selector 函数。


实现二:UIGestureRecognizerDelegate

基于实现一的发现,将目光集中到 UITapGestureRecognizer 上。查阅文档,这个 delegate 可以让开发者可以微调手势行为。经过一些测试,可以在gestureRecognizerShouldBegin:这个回调中来获取 touch point。

具体实现步骤:

  1. 给 ModalView 的UITapGestureRecognizer设置UIGestureRecognizerDelegate

  2. 在 delegate 中获取 tap 点:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;{    CGPoint point = [gestureRecognizer locationOfTouch:0 inView:self.modalView.superview];    self.lastTapPoint = point;    return YES;}
复制代码
  1. checkPointInsideMenuItem的实现不用变化


经过最终测试,这个方法可以很好的实现 ModalView 的点击位置获取,从而实现该位置的转发处理。


用户头像

teoking

关注

Monkey plays software. 2018.11.28 加入

程序员。目前主要从事Android和iOS开发。

评论

发布
暂无评论
iOS touch事件点的获取