Forward touch events to either the node or super

`_ASDisplayView` now forwards touch events to either super or it's node, depending on whether or not the node implements the methods.

fixes #199
This commit is contained in:
Ryan Nystrom 2015-01-06 14:06:40 -08:00
parent 146a83568f
commit 7b86303f20
3 changed files with 50 additions and 40 deletions

View File

@ -118,6 +118,21 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
_flags.implementsDrawParameters = ([self respondsToSelector:@selector(drawParametersForAsyncLayer:)] ? 1 : 0);
_fadeAnimationDuration = 0.1;
ASDisplayNodeMethodOverrides overrides = ASDisplayNodeMethodOverrideNone;
if (ASDisplayNodeSubclassOverridesSelector([self class], @selector(touchesBegan:withEvent:))) {
overrides |= ASDisplayNodeMethodOverrideTouchesBegan;
}
if (ASDisplayNodeSubclassOverridesSelector([self class], @selector(touchesMoved:withEvent:))) {
overrides |= ASDisplayNodeMethodOverrideTouchesMoved;
}
if (ASDisplayNodeSubclassOverridesSelector([self class], @selector(touchesCancelled:withEvent:))) {
overrides |= ASDisplayNodeMethodOverrideTouchesCancelled;
}
if (ASDisplayNodeSubclassOverridesSelector([self class], @selector(touchesEnded:withEvent:))) {
overrides |= ASDisplayNodeMethodOverrideTouchesEnded;
}
_methodOverrides = overrides;
}
- (id)init
@ -1303,50 +1318,22 @@ static NSInteger incrementIfFound(NSInteger i) {
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
ASDisplayNodeAssertMainThread();
if (!_view)
return;
// If we reach the base implementation, forward up the view hierarchy.
UIView *superview = _view.superview;
[superview touchesBegan:touches withEvent:event];
// subclass hook
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
ASDisplayNodeAssertMainThread();
if (!_view)
return;
// If we reach the base implementation, forward up the view hierarchy.
UIView *superview = _view.superview;
[superview touchesMoved:touches withEvent:event];
// subclass hook
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
ASDisplayNodeAssertMainThread();
if (!_view)
return;
// If we reach the base implementation, forward up the view hierarchy.
UIView *superview = _view.superview;
[superview touchesEnded:touches withEvent:event];
// subclass hook
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
ASDisplayNodeAssertMainThread();
if (!_view)
return;
// If we reach the base implementation, forward up the view hierarchy.
UIView *superview = _view.superview;
[superview touchesCancelled:touches withEvent:event];
// subclass hook
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer

View File

@ -151,26 +151,38 @@
#pragma mark - Event Handling + UIResponder Overrides
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
[_node touchesBegan:touches withEvent:event];
if (_node.methodOverrides & ASDisplayNodeMethodOverrideTouchesBegan) {
[_node touchesBegan:touches withEvent:event];
} else {
[super touchesBegan:touches withEvent:event];
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
[_node touchesMoved:touches withEvent:event];
if (_node.methodOverrides & ASDisplayNodeMethodOverrideTouchesMoved) {
[_node touchesMoved:touches withEvent:event];
} else {
[super touchesMoved:touches withEvent:event];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
[_node touchesEnded:touches withEvent:event];
if (_node.methodOverrides & ASDisplayNodeMethodOverrideTouchesEnded) {
[_node touchesEnded:touches withEvent:event];
} else {
[super touchesEnded:touches withEvent:event];
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
[_node touchesCancelled:touches withEvent:event];
if (_node.methodOverrides & ASDisplayNodeMethodOverrideTouchesCancelled) {
[_node touchesCancelled:touches withEvent:event];
} else {
[super touchesCancelled:touches withEvent:event];
}
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

View File

@ -22,6 +22,14 @@ BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector);
CGFloat ASDisplayNodeScreenScale();
void ASDisplayNodePerformBlockOnMainThread(void (^block)());
typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides) {
ASDisplayNodeMethodOverrideNone = 0,
ASDisplayNodeMethodOverrideTouchesBegan = 1 << 0,
ASDisplayNodeMethodOverrideTouchesCancelled = 1 << 1,
ASDisplayNodeMethodOverrideTouchesEnded = 1 << 2,
ASDisplayNodeMethodOverrideTouchesMoved = 1 << 3
};
@class _ASPendingState;
// Allow 2^n increments of begin disabling hierarchy notifications
@ -102,6 +110,9 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)());
// Creates a pendingViewState if one doesn't exist. Allows setting view properties on a bg thread before there is a view.
@property (atomic, retain, readonly) _ASPendingState *pendingViewState;
// Bitmask to check which methods an object overrides.
@property (nonatomic, assign, readonly) ASDisplayNodeMethodOverrides methodOverrides;
// Swizzle to extend the builtin functionality with custom logic
- (BOOL)__shouldLoadViewOrLayer;
- (BOOL)__shouldSize;