Created
May 4, 2014 02:02
-
-
Save elizaaverywilson/c378205ab70119f250fd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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