检测 iOS 中的不活动(无用户交互)以显示像叠加层一样的单独屏幕

Detecting inactivity (no user interaction) in iOS for showing separate Screen like an Overlay

如何检测 iOS 应用程序中的不活动或无用户交互。用于显示单独的屏幕,如叠加层或屏幕保护程序之类的东西。 与以下 link link that used to present screen overlay when the app became inactive 我可以在应用程序中显示屏幕保护程序。但是正常关闭视图控制器代码无法关闭呈现的视图控制器。

 we are presenting the custom overlay using

// The callback for when the timeout was fired.
    func applicationDidTimout(notification: NSNotification) {

       let storyboard = UIStoryboard(name: "MyStoryboard", bundle: nil)
              let vc = 
 storyboard.instantiateViewControllerWithIdentifier("myStoryboardIdentifier")
        UIApplication.shared.keyWindow?.rootViewController = vc       
    }

我们面临的问题是。呈现视图后,我们无法关闭或删除视图控制器。

来自@Prabhat Kesara 的评论和@Vanessa Forney 在助手中的回答link。我提供了以下解决方案,并且工作正常。如果有人提出这样的要求,他们可以使用这个

import UIKit
import Foundation

extension NSNotification.Name {
    public static let TimeOutUserInteraction: NSNotification.Name = NSNotification.Name(rawValue: "TimeOutUserInteraction")
}

class UserInterractionSetup: UIApplication {

    static let ApplicationDidTimoutNotification = "AppTimout"

    // The timeout in seconds for when to fire the idle timer.

    let timeoutInSeconds: TimeInterval = 1 * 60 //5 * 60 //

    var idleTimer: Timer?

    // Listen for any touch. If the screen receives a touch, the timer is reset.

    override func sendEvent(_ event: UIEvent) {

        super.sendEvent(event)


        if idleTimer != nil {

            self.resetIdleTimer()

        }

        if let touches = event.allTouches {

            for touch in touches {

                if touch.phase == UITouch.Phase.began {

                    self.resetIdleTimer()

                }

            }

        }

    }


    // Resent the timer because there was user interaction.

    func resetIdleTimer() {

        if let idleTimer = idleTimer {

            // print("1")

            let root = UIApplication.shared.keyWindow?.rootViewController

            root?.dismiss(animated: true, completion: nil)

            idleTimer.invalidate()

        }


        idleTimer = Timer.scheduledTimer(timeInterval: timeoutInSeconds, target: self, selector: #selector(self.idleTimerExceeded), userInfo: nil, repeats: false)

    }

    // If the timer reaches the limit as defined in timeoutInSeconds, post this notification.

    @objc func idleTimerExceeded() {

        print("Time Out")
         NotificationCenter.default.post(name:Notification.Name.TimeOutUserInteraction, object: nil)

        let screenSaverVC = UIStoryboard(name:"ScreenSaver", bundle:nil).instantiateViewController(withIdentifier:"LandingPageViewController") as! LandingPageViewController

        if let presentVc = TopMostViewController.sharedInstance.topMostViewController(controller: screenSaverVC){


            let root: UINavigationController = UIApplication.shared.keyWindow!.rootViewController as! UINavigationController

            if let topView = root.viewControllers.last?.presentedViewController {

                topView.dismiss(animated: false) {

                    root.viewControllers.last?.navigationController?.present(presentVc, animated: true, completion: nil)

                }

            }else if let topViewNavigation = root.viewControllers.last {

                topViewNavigation.navigationController?.present(presentVc, animated: true, completion: nil)



            }

        }

    }

}

我遇到的困难是在已经呈现的视图之上呈现叠加层或屏幕保护程序。这种情况,我们也在上述解决方案中处理。 编码愉快 :)