zoukankan      html  css  js  c++  java
  • ios-runtime拦截touch事件,展示用户触摸效果

    【展示效果说明】

      对 app 操作录屏时,展示出手指在 app 上的触摸效果可以看到具体点击情况,感觉这样比较直观方便,也不用做视频后期了。

      这里简单用 runtime 实现了一个这样的效果,不需要修改任何代码,只要将 UIWindow+Touch.m 分类导入工程即可。

      展示效果如下:

        

    【实现思路】

      1. 要拦截到所有的点击事件,获取点击相对于屏幕的位置。ios中事件分发中点击事件应该是这样的: 系统第一个得到点击事件 -> 分发给application -> 分发给 window -> window 内的子 view 层层遍历。

      2. 只是一个小功能,要让这个功能可控,不要对原有代码进行改动。用 runtime 交换系统方法进行touch事件拦截,在分发事件时加入自己的一些代码。

      3. 拿到触摸点的位置后创建 view 展示一些动画效果就可以。

      上面第1点中可以知道,事件在application中进行拦截最靠谱,因为系统第一个分发就是给它,但这里操作都是UI相关,所以UI相关事件放在 window 上进行处理比较合适。所以这里就是交换的 window 对象的 sendEvent: 方法。

    【代码】

      新建 UIWindow + Touch 分类,在 .m 文件中交换 sendEvent 方法,同时加上自己处理的代码,主要是在获取点击x,y的位置,然后添加一个view,加上一点动画,最终就有了上述效果。 UIWindow + Touch.m 代码如下:

    #import "UIWindow+Touch.h
    #import <objc/runtime.h>
    @implementation UIWindow (Touch) + (void)load {
      // 交换方法 Method m1
    = class_getInstanceMethod([self class], @selector(sendEvent:)); Method m2 = class_getInstanceMethod([self class], @selector(ljs_sendEvent:)); method_exchangeImplementations(m1, m2); } - (void)ljs_sendEvent:(UIEvent *)event { [self ljs_sendEvent:event];
      // 对点击事件进行处理 [self dealTouch:
    event]; } - (void)dealTouch:(UIEvent *)event { UITouch *touch = event.allTouches.anyObject; if (touch.phase == UITouchPhaseEnded) { return; } static CGFloat width = 20; if (event.type == UIEventTypeTouches) { CGPoint point = [event.allTouches.anyObject locationInView:self]; CGFloat oringX = point.x - width / 2; CGFloat oringY = point.y - width / 2; CGRect rect = CGRectMake(oringX, oringY, width, width); UIView *blackV = [[UIView alloc] initWithFrame:rect]; blackV.alpha = 0.3; blackV.layer.cornerRadius = width / 2; blackV.backgroundColor = [UIColor purpleColor]; [self addSubview:blackV]; [self bringSubviewToFront:blackV]; // 设置动画 CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; animation.duration = 0.3; animation.fromValue = @1; animation.toValue = @2; animation.fillMode = @"backwards"; animation.removedOnCompletion = YES; [blackV.layer addAnimation:animation forKey:@"an1"]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.27 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [blackV removeFromSuperview]; }); } } @end
  • 相关阅读:
    软工实践1816-第四次作业
    软工实践1816-第三次作业
    软工实践1816-第二次作业
    Alpha 冲刺 (3/10)
    Alpha 冲刺 (2/10)
    Alpha 冲刺 (1/10)
    福大软工 · 第七次作业
    福大软工 · 第八次作业(课堂实战)- 项目UML设计(团队)
    福大软工1816 · 第六次作业
    福大软工1816 · 第五次作业
  • 原文地址:https://www.cnblogs.com/buerjj/p/8551710.html
Copyright © 2011-2022 走看看