Skip to content

Instantly share code, notes, and snippets.

@elizaaverywilson
Created May 4, 2014 02:02
Show Gist options
  • Save elizaaverywilson/c378205ab70119f250fd to your computer and use it in GitHub Desktop.
Save elizaaverywilson/c378205ab70119f250fd to your computer and use it in GitHub Desktop.
#import "NNForwardTouchView.h"
#import "NNGameViewsManagerModel.h"
#import "DDTTYLogger.h"
#import "DDLog.h"
#ifdef DEBUG
static const int ddLogLevel = LOG_LEVEL_DEBUG;
#else
static const int ddLogLevel = LOG_LEVEL_OFF;
#endif
@interface NNForwardTouchView ()
@property UIView *gameViewRootView;
@end
@implementation NNForwardTouchView
#pragma mark -- setup
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[self setup];
}
return self;
}
- (void)setup {
static dispatch_once_t onceToken;
dispatch_once (&onceToken, ^{
UIView *rootView = self;
while (1) {
if (rootView.superview) {
rootView = rootView.superview;
} else {
break;
}
}
[self setGameViewRootView: [rootView viewWithTag: NNGameViewRootViewTag]];
});
}
#pragma mark -- responder
- (UIResponder*)responderForPoint:(CGPoint)point {
[self setup];
if (!self.gameViewRootView) {
DDLogError(@"GameViewRootView is nil!");
} else {
DDLogVerbose(@"GameViewRootView: %@", self.gameViewRootView);
}
DDLogDebug(@"(%f, %f)", point.x, point.y);
UIResponder *responder = [self responderOf: self.gameViewRootView forPoint:point];
if (!responder) {
DDLogError(@"Responder is nil!");
}
return responder;
}
- (UIResponder*)responderOf:(UIView*)view forPoint:(CGPoint)point {
DDLogDebug(@"view:%@ subviews: %@ view.userInteractionEnabled: %i", view, view.subviews, view.userInteractionEnabled);
if (view) {
if (!view.hidden) {
CGRect absoluteRect = [self.gameViewRootView convertRect:view.frame fromView:view.superview];
if (CGRectContainsPoint(absoluteRect, point)) {
DDLogVerbose(@"Frame Details | (%f, %f) frame: (%f-%f, %f-%f) absoluteFrame: (%f-%f, %f-%f)", point.x, point.y, view.frame.origin.x, view.frame.origin.x + view.frame.size.height, view.frame.origin.y, view.frame.origin.y + view.frame.size.width, absoluteRect.origin.x, absoluteRect.origin.x + absoluteRect.size.height, absoluteRect.origin.y, absoluteRect.origin.y + absoluteRect.size.width);
if ([self object:view isKindOfAClass: [self allowedResponderClasses]]) {
if (view.userInteractionEnabled) {
DDLogDebug(@"View confirmed: %@", view);
return view;
}
} else {
for (NSUInteger i = 0; i < view.subviews.count; i++) {
UIView *subview = (UIView*)view.subviews[i];
UIResponder *responder = [self responderOf: subview forPoint:point];
if (responder) {
DDLogDebug(@"Responder confirmed: %@", responder);
return responder;
}
}
}
}
}
}
DDLogDebug(@"Returning nil for responder.");
return nil;
}
- (BOOL)object:(NSObject*)object isKindOfAClass:(NSArray*)classes {
for (Class allowedClasses in (Class)classes) {
if ([object isKindOfClass: allowedClasses]) {
return YES;
}
}
return NO;
}
- (NSArray*)allowedResponderClasses {
return [NSArray arrayWithObjects:
[UIButton class],
nil];
}
#pragma mark -- touches
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
NSArray *touchesArray = [touches allObjects];
UIResponder *responder = [self responderForTouches:touchesArray];
[responder touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
NSArray *touchesArray = [touches allObjects];
UIResponder *responder = [self responderForTouches:touchesArray];
[responder touchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
NSArray *touchesArray = [touches allObjects];
UIResponder *responder = [self responderForTouches:touchesArray];
[responder touchesEnded:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
NSArray *touchesArray = [touches allObjects];
UIResponder *responder = [self responderForTouches:touchesArray];
[responder touchesCancelled:touches withEvent:event];
}
- (UIResponder*)responderForTouches:(NSArray*)touchesArray {
for (NSUInteger i = 0; i < touchesArray.count; i++) {
UITouch *touch = (UITouch*)touchesArray[i];
CGPoint point = [touch locationInView: self.gameViewRootView];
UIResponder *responder = [self responderForPoint:point];
if (responder) {
return responder;
}
}
return nil;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment