Jonas Stawski
Jonas Stawski

Reputation: 6752

Is there a global touched event?

Is there a way to listen to a global touch event? I want to be notified when the screen was touched. Right now I'm overriding the TouchesBegan on my View, but it doesn't seem like it bubbles up. i.e. If I touch a button or the keyboard the method never gets called. Maybe through the use of NSNotificationCenter or something similar.

Thanks,

Upvotes: 0

Views: 1177

Answers (2)

Caleb
Caleb

Reputation: 124997

Right now I'm overriding the TouchesBegan on my View, but it doesn't seem like it bubbles up.

You're right -- touches are delivered starting from the view at the root of the view hierarchy (i.e. the window) and progressing down through the view hierarchy until the touched view is found. Take a look at UIView's -hitTest:withEvent: method. Starting with the window, that method is called to find the hit subview, and then that same method is called on the subview, and so on.

Upvotes: 0

Rok Jarc
Rok Jarc

Reputation: 18865

I posted some code here that might help. But that code is mixed with OP's code, so here's a clean version.

What you can do is subclass UIWindow and pass it to application delegate as its window.

Code would look something like:

MyKindOfWindow.h

#import <UIKit/UIKit.h>

@protocol MyKindOfWindowDelegate;

@interface MyKindOfWindow : UIWindow

@property (assign) id <MyKindOfWindowDelegate> touchDelegate;

@end

@protocol MyKindOfWindowDelegate <NSObject>

@required
- (void) windowTouch:(UIEvent *)event;
@end

MyKindOfWindow.m

#import "MyKindOfWindow.h"

@implementation MyKindOfWindow

@synthesize touchDelegate = _touchDelegate;

- (id)initWithFrame:(CGRect)aRect
{
    if ((self = [super initWithFrame:aRect])) {

        _touchDelegate = nil;
    }
    return self;
}

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

    if (event.type == UIEventTypeTouches)
        [_touchDelegate windowTouch:event]; 
}

@end

Your AppDelegate would of course need to follow MyKindOfWindowDelegate protocol (implement - (void) windowTouch:(UIEvent *)event method).

didFinishLaunchingWithOptions: would look like:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[MyKindOfWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [(MyKindOfWindow *)self.window setTouchDelegate:self];  //!!make your AppDelegate a delegate of self.window

    //this part of code might be different for your needs
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil];
    } else {
        self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil];
    }

    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

Upvotes: 1

Related Questions