如何在Swift 2中检测所有触摸 [英] How to detect all touches in Swift 2

查看:68
本文介绍了如何在Swift 2中检测所有触摸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为使用Swift 2开发的应用创建超时功能,但是在swift 2中,您可以将此代码放入应用委托中,并且可以正常工作,但它不会检测到任何键盘按下或按钮按下,文字栏按下等等:

I'm trying to create a timeout function for an app I'm develop using Swift 2 but in swift 2, you can put this code in the app delegate and it works but it does not detect any keyboard presses, button presses, textfield presses, and etc:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    super.touchesBegan(touches, withEvent: event);
    let allTouches = event!.allTouches();

    if(allTouches?.count > 0) {
        let phase = (allTouches!.first as UITouch!).phase;
        if(phase == UITouchPhase.Began || phase == UITouchPhase.Ended) {
            //Stuff
            timeoutModel.actionPerformed();
        }
    }
}

在swift 2之前,我能够拥有AppDelegate子类UIApplication并重写sendEvent:像这样:

Before swift 2, I was able to have the AppDelegate subclass UIApplication and override sendEvent: like this:

-(void)sendEvent:(UIEvent *)event
{
    [super sendEvent:event];

    // Only want to reset the timer on a Began touch or an Ended touch, to reduce the number of timer resets.
    NSSet *allTouches = [event allTouches];
    if ([allTouches count] > 0) {
        // allTouches count only ever seems to be 1, so anyObject works here.
        UITouchPhase phase = ((UITouch *)[allTouches anyObject]).phase;
        if (phase == UITouchPhaseBegan || phase == UITouchPhaseEnded)
            [[InactivityModel instance] actionPerformed];
    }
}

上面的代码适用于每次触摸,但是只有当视图不在该UIWindow层次之上时,等效的快捷方式才起作用?

The code above works for every touch but the swift equivalent only works when a view does not exist above that UIWindow's hierarchy?

有人知道一种检测应用程序中每一次触摸的方法吗?

Does anyone know a way to detect every touch in the application?

推荐答案

由于我的应用程序中存在类似内容,因此我试图对其进行修复:

As I have something similar in my application, I just tried to fix it:

  • 覆盖UIWindow中的sendEvent-不起作用
  • 在委托中覆盖sendEvent-不起作用
  • override sendEvent in UIWindow - doesn't work
  • override sendEvent in delegate - doesn't work

因此,唯一的方法是提供自定义的UIApplication子类.到目前为止,我的代码(可在iOS 9上运行)是:

So the only way is to provide custom UIApplication subclass. My code so far (works on iOS 9) is:

@objc(MyApplication) class MyApplication: UIApplication {

  override func sendEvent(event: UIEvent) {
    //
    // Ignore .Motion and .RemoteControl event
    // simply everything else then .Touches
    //
    if event.type != .Touches {
      super.sendEvent(event)
      return
    }

    //
    // .Touches only
    //
    var restartTimer = true

    if let touches = event.allTouches() {
      //
      // At least one touch in progress?
      // Do not restart auto lock timer, just invalidate it
      //
      for touch in touches.enumerate() {
        if touch.element.phase != .Cancelled && touch.element.phase != .Ended {
          restartTimer = false
          break
        }
      }
    }

    if restartTimer {
      // Touches ended || cancelled, restart auto lock timer
      print("Restart auto lock timer")
    } else {
      // Touch in progress - !ended, !cancelled, just invalidate it
      print("Invalidate auto lock timer")
    }

    super.sendEvent(event)
  }

}

为什么有@objc(MyApplication).那是因为Swift用一种不同于Objective-C的方式来命名名称,它只是说-我在Objective-C中的类名称是MyApplication.

Why there's @objc(MyApplication). That's because Swift mangles names in a different way then Objective-C and it just says - my class name in Objective-C is MyApplication.

要使其正常运行,请打开info.plist并使用 Principal class 键和MyApplication值添加行(MyApplication@objc(...)中的内容,而不是您的Swift类名).原始密钥为NSPrincipalClass.

To make it working, open your info.plist and add row with Principal class key and MyApplication value (MyApplication is what's inside @objc(...), not your Swift class name). Raw key is NSPrincipalClass.

这篇关于如何在Swift 2中检测所有触摸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆