通过Swift中的触摸检测应用程序何时处于活动状态或非活动状态[重复]

Posted

技术标签:

【中文标题】通过Swift中的触摸检测应用程序何时处于活动状态或非活动状态[重复]【英文标题】:Detecting when an app is active or inactive through touches in Swift [duplicate] 【发布时间】:2016-03-23 16:16:51 【问题描述】:

哪些代码可用于检测用户何时与应用交互以及何时用户不与应用交互?

目前我有一个ViewController 和一个UIView,它通过覆盖触摸、接收平移手势和点击手势来接收触摸。这个问题的解决方案需要与当前的手势分开,或者高于这些手势。

是否有一个手势识别器位于所有其他功能之上,可以告诉我的应用何时收到手势以及何时没有收到手势?

当应用处于活动状态时,有没有办法监控应用是否正在接收触摸以及何时没有接收并根据需要调用函数,例如:

func appActive()
    print("App received input from a touch, tap, swipe, long press etc.")


func appInactive()
    print("App stopped receiving any input.")

谢谢。

【问题讨论】:

当不是活动状态时,您无法获得任何触摸事件,对于活动状态,您可以通过将手势放在窗口等中来获得触摸... @Sulthan 问题在于 OC 而不是 Swift。由于 Swift 中没有 main.m 文件,因此尚不清楚该答案是如何工作的。这里的答案是 Swift 中的问题。 @Sulthan 我从来没有要求“给我代码”。 S/O S/E 是问答。有答案吗?伟大的!如果没有,请不要破坏其他好的答案。如果你只学过 Swift,OC 问题是不够的。如果您对 Swift 没有帮助,请不要关闭问题,尤其是当语言完全不同时!如果没有人能够提供帮助,我找到了两个答案,在其他网络教程中找到了答案,一路参考以将它们组合成一个简洁的有凝聚力的答案,而不是一个完全神秘的答案,以便其他人可以逐步学习并公开使用他们选择的代码。 @Sulthan 这不是另一个 Swift 答案的副本。我已经从几个答案中提取了最好的部分,参考并链接到它们,以得出适合该问题所提出问题的更好答案。 @user4806509 问题是重复的。如果您对该问题有更好的答案,请在此处发布。您还可以在那里改进(编辑或评论)已经存在的答案。您不必为了发布新答案而创建重复的问题。 【参考方案1】:

Swift 2. Xcode 7.2。在 ios 7 - 9 上测试。

改编自: How to detect all touches in Swift 2 Subclass UIApplication with Swift


1 - 找到您项目的 Swift 文件 AppDelegate.swift,并注释掉 @UIApplicationMain

//@UIApplicationMain

2 - 将一个新的 Swift 文件添加到您的项目中,该文件完全命名为 main.swift,并添加代码:

import UIKit

UIApplicationMain(  
CommandLine.argc, UnsafeMutableRawPointer(CommandLine.unsafeArgv)  
    .bindMemory( to: UnsafeMutablePointer<Int8>.self,  
        capacity: Int(CommandLine.argc)), nil, NSStringFromClass(AppDelegate.self))  

3 - 将一个新的 Swift 文件添加到您的项目中,该文件完全命名为 UIApplication.swift,并添加代码:

import UIKit

@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 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 timer
            print("Touches ended. Restart timer")
         else 
            // Touches in progress - !ended, !cancelled, just invalidate it
            print("Touches in progress. Invalidate timer")
        
    
        super.sendEvent(event)
    


4 - 找到您项目的Info.plist 文件,并添加一个新密钥(Xcode 菜单:Editor &gt; Add Item,选择或键入密钥Principal class,字符串值为MyApplication


5 - 运行您的项目!


【讨论】:

我收到一个错误,即使用未解析的标识符“进程” @Bharathi 你找到方法了吗? 改用这行代码。UIApplicationMain(CommandLine.argc, UnsafeMutableRawPointer(CommandLine.unsafeArgv) .bindMemory( to: UnsafeMutablePointer.self, capacity: Int(CommandLine.argc)), nil , NSStringFromClass(AppDelegate))【参考方案2】:

拦截应用程序的任何触摸的一种方法是创建一个自定义 UIWindow,它会在不取消触摸的情况下捕获触摸。

class CustomWindow: UIWindow 

    override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool 
        // Do any action you would like to perform to indicate the application is active
        return false
    


您必须在 Application Delegate 中添加此窗口,并将其级别设置为高于主窗口。

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate 

    var window: UIWindow?
    var topWindow: CustomWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
    
        topWindow = CustomWindow(frame: UIScreen.mainScreen().bounds)
        topWindow?.rootViewController = UIViewController()
        topWindow?.windowLevel = UIWindowLevelNormal + 1
        topWindow?.hidden = false
        return true
    

【讨论】:

谢谢。这似乎告诉我用户何时开始交互,但似乎并没有告诉我用户何时停止交互。例如,如果用户连续触摸屏幕 5 秒钟,即触摸移动或平移或按住按钮,我似乎得到了初始交互,但它并没有告诉我用户仍在交互或用户何时交互完成交互,例如修饰。如何修改代码以在交互停止时发出警报?另外,是否有可能找到我们触发了什么类型的触摸事件(即长按、触摸移动等)。 @tanguy-g 不错的解决方案,我几乎很惭愧我不得不谷歌这个......

以上是关于通过Swift中的触摸检测应用程序何时处于活动状态或非活动状态[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何检测 UIAccessibilityRequestGuidedAccessSession 在设备上是不是处于活动状态,iOS swift?

允许 UIScrollView 在长按处于活动状态时通过第二次触摸滚动

有没有办法检测浏览器窗口当前是否处于活动状态?

当我的应用在IOS中处于活动状态时如何阻止屏幕截图[关闭]

如何检测用户何时专门通过“最近使用的应用”返回应用?

如何在特定视口上设置触摸手势/hammer.js 处于活动状态?