简体   繁体   中英

How to detect screen activity via UIViewController (Swift, iOS 9)

I want to create a UIViewController that has a timeout that will unwind a segue after a certain amount of time, but detects when there's screen activity and resets the timer. Think a password entry screen where you want the screen to timeout if the device is sitting there idle. I suppose the iphone/ipad will timeout and then when you unlock and go back to that app, I want the segue to unwind in that case as well. What is the best approach for this?

Decalare a timer

var timer = NSTimer() 

In your viewDidLoad do set the timer to whatever you like

Here terminateApp will be called after 60 seconds

timer = NSTimer.scheduledTimerWithTimeInterval(60, target: self, selector: Selector("terminateApp"), userInfo: nil, repeats: true)

func terminateApp(){
    // Do your segue and invalidate the timer
    timer.invalidate()
}

But if the user presses the view you want to invalidate the timer and start a new timer, do that by:

In your viewDidLoad add a gestureRecognizer that will call resetTimer when the user touches the screen:

let resetTimer = UITapGestureRecognizer(target: self, action: "resetTimer");
self.view.userInteractionEnabled = true
self.view.addGestureRecognizer(resetTimer)

func resetTimer(){
    // invaldidate the current timer and start a new one
    timer.invalidate()
    timer = NSTimer.scheduledTimerWithTimeInterval(60, target: self, selector: Selector("terminateApp"), userInfo: nil, repeats: true)
}

You can either register your view controller for UIApplicationDidBecomeActiveNotification

NSNotificationCenter.defaultCenter().addObserver(self, selector: "yourFunction", name: UIApplicationDidBecomeActiveNotification, object: nil)

or call relevant functions in your view controllers from applicationDidBecomeActive in your AppDelegate.

You can also handle things when applicationDidResignActive is called, to do something when you go to background rather than when you come back. This has the benefit of being an immediate change if the user takes a phone call etc, rather than waiting on a timer. You could use the timer approach, to handle inactivity when the app is still on screen - and then invalidate the timer when the app resigns active, using the app delegate methods.

You have a couple of options depending on what interaction you're trying to support.

To detect touches you might want to set your UIViewController 's view to be some customer UIView subclass which overrides -hitTest:withEvent: to report touch interactions to it's controller or some other delegate. Alternately you could define a gesture recognizer to report touches within that view. Either one will detect touches on subviews of the controller but not necessarily keyboard events (either from an on screen keyboard which is not part of your controller's view hierarchy or from a hardware keyboard).

For keyboard events you may need to rely on a UITextFieldDelegate and it's -textField:shouldChangeCharactersInRange:replacementString: . I can't immediately think of an application or view wide way to detect those inputs.

For detecting the device becoming locked or the app losing focus you might want to react to the UIApplicationWillResignActiveNotification notification.

Which of those you want requires more detail than I can extract from your question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM