Forward touches to super instead of the superview

fixes #402
This commit is contained in:
Ryan Nystrom 2015-03-26 17:09:45 -07:00
parent dd10fda42c
commit b6715b5cf9
8 changed files with 139 additions and 26 deletions

View File

@ -20,6 +20,15 @@
//@property (atomic, retain) UIColor *backgroundColor;
@property (nonatomic) UITableViewCellSelectionStyle selectionStyle;
/*
* ASCellNode must forward touch events in order for UITableView and UICollectionView tap handling to work. Overriding
* these methods (e.g. for highlighting) requires the super method be called.
*/
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event ASDISPLAYNODE_REQUIRES_SUPER;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event ASDISPLAYNODE_REQUIRES_SUPER;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event ASDISPLAYNODE_REQUIRES_SUPER;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event ASDISPLAYNODE_REQUIRES_SUPER;
@end

View File

@ -8,8 +8,9 @@
#import "ASCellNode.h"
#import "ASDisplayNode+Subclasses.h"
#import "ASTextNode.h"
#import <AsyncDisplayKit/_ASDisplayView.h>
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
#import <AsyncDisplayKit/ASTextNode.h>
#pragma mark -
@ -28,12 +29,52 @@
return self;
}
- (instancetype)initWithLayerBlock:(ASDisplayNodeLayerBlock)viewBlock
{
ASDisplayNodeAssertNotSupported();
return nil;
}
- (instancetype)initWithViewBlock:(ASDisplayNodeViewBlock)viewBlock
{
ASDisplayNodeAssertNotSupported();
return nil;
}
- (void)setLayerBacked:(BOOL)layerBacked
{
// ASRangeController expects ASCellNodes to be view-backed. (Layer-backing is supported on ASCellNode subnodes.)
ASDisplayNodeAssert(!layerBacked, @"ASCellNode does not support layer-backing.");
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert([self.view isKindOfClass:_ASDisplayView.class], @"ASCellNode views must be of type _ASDisplayView");
[(_ASDisplayView *)self.view __forwardTouchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert([self.view isKindOfClass:_ASDisplayView.class], @"ASCellNode views must be of type _ASDisplayView");
[(_ASDisplayView *)self.view __forwardTouchesMoved:touches withEvent:event];
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert([self.view isKindOfClass:_ASDisplayView.class], @"ASCellNode views must be of type _ASDisplayView");
[(_ASDisplayView *)self.view __forwardTouchesEnded:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
ASDisplayNodeAssertMainThread();
ASDisplayNodeAssert([self.view isKindOfClass:_ASDisplayView.class], @"ASCellNode views must be of type _ASDisplayView");
[(_ASDisplayView *)self.view __forwardTouchesCancelled:touches withEvent:event];
}
@end

View File

@ -1424,22 +1424,22 @@ static NSInteger incrementIfFound(NSInteger i) {
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// subclass hook
// subclass hook
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
// subclass hook
// subclass hook
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// subclass hook
// subclass hook
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
// subclass hook
// subclass hook
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer

View File

@ -85,6 +85,18 @@
return self;
}
- (instancetype)initWithLayerBlock:(ASDisplayNodeLayerBlock)viewBlock
{
ASDisplayNodeAssertNotSupported();
return nil;
}
- (instancetype)initWithViewBlock:(ASDisplayNodeViewBlock)viewBlock
{
ASDisplayNodeAssertNotSupported();
return nil;
}
- (void)dealloc
{
_textKitComponents.textView.delegate = nil;

View File

@ -94,6 +94,18 @@
return self;
}
- (instancetype)initWithLayerBlock:(ASDisplayNodeLayerBlock)viewBlock
{
ASDisplayNodeAssertNotSupported();
return nil;
}
- (instancetype)initWithViewBlock:(ASDisplayNodeViewBlock)viewBlock
{
ASDisplayNodeAssertNotSupported();
return nil;
}
- (CGSize)calculateSizeThatFits:(CGSize)constrainedSize
{
ASDN::MutexLocker l(_imageLock);

View File

@ -146,6 +146,18 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
return self;
}
- (instancetype)initWithLayerBlock:(ASDisplayNodeLayerBlock)viewBlock
{
ASDisplayNodeAssertNotSupported();
return nil;
}
- (instancetype)initWithViewBlock:(ASDisplayNodeViewBlock)viewBlock
{
ASDisplayNodeAssertNotSupported();
return nil;
}
- (void)dealloc
{
if (_shadowColor != NULL) {

View File

@ -14,4 +14,11 @@
@interface _ASDisplayView : UIView
// These methods expose a way for ASDisplayNode touch events to let the view call super touch events
// Some UIKit mechanisms, like UITableView and UICollectionView selection handling, require this to work
- (void)__forwardTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)__forwardTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)__forwardTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)__forwardTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
@end

View File

@ -151,38 +151,58 @@
#pragma mark - Event Handling + UIResponder Overrides
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (_node.methodOverrides & ASDisplayNodeMethodOverrideTouchesBegan) {
[_node touchesBegan:touches withEvent:event];
} else {
[super 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
{
if (_node.methodOverrides & ASDisplayNodeMethodOverrideTouchesMoved) {
[_node touchesMoved:touches withEvent:event];
} else {
[super 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
{
if (_node.methodOverrides & ASDisplayNodeMethodOverrideTouchesEnded) {
[_node touchesEnded:touches withEvent:event];
} else {
[super 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
{
if (_node.methodOverrides & ASDisplayNodeMethodOverrideTouchesCancelled) {
[_node touchesCancelled:touches withEvent:event];
} else {
[super touchesCancelled:touches withEvent:event];
}
if (_node.methodOverrides & ASDisplayNodeMethodOverrideTouchesCancelled) {
[_node touchesCancelled:touches withEvent:event];
} else {
[super touchesCancelled:touches withEvent:event];
}
}
- (void)__forwardTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
}
- (void)__forwardTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
}
- (void)__forwardTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesEnded:touches withEvent:event];
}
- (void)__forwardTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesCancelled:touches withEvent:event];
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event