Listen to all touch events in an iOS app

Is it possible to somehow listen to, and catch, all the touch events occurring in an app?

The app I’m currently developing will be used in showrooms and information kiosks and I would therefore like to revert to the start section of the app if no touches has been received for a given couple of minutes. A sort of screensaver functionality, if you will. I’m planning to implement this by having a timer running in the background, which should be reset and restarted every time a touch event occurs somewhere in the app. But how can I listen to the touch events? Any ideas or suggestions?

  • iOS 9 `-webkit-overflow-scrolling:touch` and `overflow: scroll` breaks scrolling capability
  • How to get PDF annotations when i touch on ipad screen
  • iOS - AVAudioPlayer doesn't continue to next song while in background
  • Make touch-area for SKLabelNode bigger for small characters
  • How to prevent multiple event on same UIButton in iOS?
  • Simulate touch on iphone
  • 5 Solutions Collect From Internet About “Listen to all touch events in an iOS app”

    It’s really easy.

    You need a subclass of UIApplication (let’s call it MyApplication).

    You modify your main.m to use it:

    
    return UIApplicationMain(argc, argv, @"MyApplication", @"MyApplicationDelegate");
    
    

    And you override the method [MyApplication sendEvent:]:

    
    - (void)sendEvent:(UIEvent*)event {
        //handle the event (you will probably just reset a timer)
    
        [super sendEvent:event];
    }
    
    

    A subclass of UIWindow could be used to do this, by overriding hitTest:. Then in the XIB of your main window, there is an object usually simply called Window. Click that, then on the right in the Utilities pane go to the Identities (Alt-Command-3). In the Class text field, enter the name of your UIWindow subclass.

    MyWindow.h

    @interface MyWindow : UIWindow
    @end
    

    MyWindow.m

    @implementation MyWindow
    
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
    {
        UIView *res;
    
        res = [super hitTest:point withEvent:event];
    
        // Setup/reset your timer or whatever your want to do.
        // This method will be called for every touch down,
        // but not for subsequent events like swiping/dragging.
        // Still, might be good enough if you want to measure
        // in minutes.
    
        return res;
    }   
    
    @end
    

    Create a Class “VApplication” that extends from UIApplication
    and paste these code to corresponding class

    VApplication.h

    #import <Foundation/Foundation.h>
    
    // # of minutes before application times out
    #define kApplicationTimeoutInMinutes 10
    
    // Notification that gets sent when the timeout occurs
    #define kApplicationDidTimeoutNotification @"ApplicationDidTimeout"
    
    /**
     * This is a subclass of UIApplication with the sendEvent: method 
     * overridden in order to catch all touch events.
     */
    
    @interface VApplication : UIApplication
    {
        NSTimer *_idleTimer;
    }
    
    /**
     * Resets the idle timer to its initial state. This method gets called
     * every time there is a touch on the screen.  It should also be called
     * when the user correctly enters their pin to access the application.
     */
    - (void)resetIdleTimer;
    
    @end
    

    VApplication.m

    #import "VApplication.h"
    #import "AppDelegate.h"
    
    @implementation VApplication
    
    - (void)sendEvent:(UIEvent *)event
    {
        [super sendEvent:event];
        // Fire up the timer upon first event
        if(!_idleTimer) {
            [self resetIdleTimer];
        }
    
        // Check to see if there was a touch event
        NSSet *allTouches       = [event allTouches];
    
        if  ([allTouches count] > 0)
            {
            UITouchPhase phase  = ((UITouch *)[allTouches anyObject]).phase;
            if  (phase == UITouchPhaseBegan)
                {
                [self resetIdleTimer];         
                }
            }
    }
    
    - (void)resetIdleTimer 
    {
        if  (_idleTimer)
            {
            [_idleTimer invalidate];
            }
    
        // Schedule a timer to fire in kApplicationTimeoutInMinutes * 60
    
    
    //  int timeout =   [AppDelegate getInstance].m_iInactivityTime;
        int timeout =   3;
        _idleTimer = [NSTimer scheduledTimerWithTimeInterval:timeout
                                                      target:self 
                                                    selector:@selector(idleTimerExceeded) 
                                                    userInfo:nil 
                                                     repeats:NO];
    
    }
    
    - (void)idleTimerExceeded
    {
        /* Post a notification so anyone who subscribes to it can be notified when
         * the application times out */
    
    
        [[NSNotificationCenter defaultCenter]
         postNotificationName:kApplicationDidTimeoutNotification object:nil];
    }
    
    
    @end
    

    Replace the Class name “VApplication” to our

    Main.m

    file like this

    int main(int argc, char * argv[])
    {
        @autoreleasepool {
            return UIApplicationMain(argc, argv, @"VApplication", NSStringFromClass([AppDelegate class]));
    
        }
    }
    

    Register a notification for your corresponding view controller

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidTimeout:) name:kApplicationDidTimeoutNotification object:nil];
    

    And once the timeout occur the notification will fire and handle the event like this

    - (void) applicationDidTimeout:(NSNotification *) notif //inactivity lead to any progress
    {
    
    
    }
    

    You could put a transparent view at the top of the view hierarchy, and choose in that view whether to handle the touch events it receives or pass them through to lower views.

    You can use a tap gesture recognizer for this. Subclass UITapGestureRecognizer and import <UIKit/UIGestureRecognizerSubclass.h>. This defines touchesBegan:, touchesMoved:, touchesEnded: and touchesCancelled:. Put your touch-handling code in the appropriate methods.

    Instantiate the gesture recognizer in application:didFinishLaunchingWithOptions: and add it to UIWindow. Set cancelsTouchesInView to NO and it’ll pass all touches through transparently.

    Credit: this post.