diff --git a/AsyncDisplayKit/ASCellNode+Internal.h b/AsyncDisplayKit/ASCellNode+Internal.h new file mode 100644 index 0000000000..feb816467d --- /dev/null +++ b/AsyncDisplayKit/ASCellNode+Internal.h @@ -0,0 +1,15 @@ +// +// ASCellNode+Internal.h +// Pods +// +// Created by Max Gu on 2/19/16. +// +// + +#import "ASCellNode.h" + +@interface ASCellNode (Internal) + +@property (nonatomic, assign) BOOL shouldObserveVisibility; + +@end diff --git a/AsyncDisplayKit/ASCellNode.h b/AsyncDisplayKit/ASCellNode.h index d1e575383e..1267ff0920 100644 --- a/AsyncDisplayKit/ASCellNode.h +++ b/AsyncDisplayKit/ASCellNode.h @@ -16,6 +16,7 @@ typedef NSUInteger ASCellNodeAnimation; @protocol ASCellNodeLayoutDelegate +- (void)scrollViewDidScroll:(UIScrollView *)scrollView cellFrameInScrollView:(CGRect)cellFrame; /** * Notifies the delegate that the specified cell node has done a relayout. * The notification is done on main thread. @@ -24,6 +25,19 @@ typedef NSUInteger ASCellNodeAnimation; * @param sizeChanged `YES` if the node's `calculatedSize` changed during the relayout, `NO` otherwise. */ - (void)nodeDidRelayout:(ASCellNode *)node sizeChanged:(BOOL)sizeChanged; + +<<<<<<< HEAD +======= +@optional +/** + * Notifies the delegate that the specified cell node has scrolled + * + * @param node: A node informing the delegate about the scroll + * @param cellFrame: The frame of the cell that has just scrolled + */ +- (void)visibleNodeDidScroll:(ASCellNode *)node inScrollView:(UIScrollView *)scrollView withCellFrame:(CGRect)cellFrame; +>>>>>>> 4b8216f... Adding scroll visibility + @end /** @@ -75,6 +89,7 @@ typedef NSUInteger ASCellNodeAnimation; */ @property (nonatomic, weak) id layoutDelegate; +@property (nonatomic, assign) BOOL shouldObserveVisibility; /* * 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. @@ -107,6 +122,12 @@ typedef NSUInteger ASCellNodeAnimation; */ - (instancetype)initWithViewControllerBlock:(ASDisplayNodeViewControllerBlock)viewControllerBlock didLoadBlock:(ASDisplayNodeDidLoadBlock)didLoadBlock; +<<<<<<< HEAD +- (void)updateScrollSituationWithScrollVIew:(UIScrollView *)scrollView; +======= +- (void)_visibleNodeDidScroll:(UIScrollView *)scrollView withCellFrame:(CGRect)cellFrame; + +>>>>>>> 4b8216f... Adding scroll visibility @end diff --git a/AsyncDisplayKit/ASCellNode.m b/AsyncDisplayKit/ASCellNode.m index df7040d92e..8ed29380a0 100644 --- a/AsyncDisplayKit/ASCellNode.m +++ b/AsyncDisplayKit/ASCellNode.m @@ -6,9 +6,10 @@ * of patent rights can be found in the PATENTS file in the same directory. */ -#import "ASCellNode.h" +#import "ASCellNode+Internal.h" #import "ASInternalHelpers.h" +#import "ASCollectionView.h" #import #import #import @@ -36,7 +37,9 @@ // Use UITableViewCell defaults _selectionStyle = UITableViewCellSelectionStyleDefault; self.clipsToBounds = YES; - + if ([self.layoutDelegate respondsToSelector:@selector(visibleNodeDidScroll:inScrollView:withCellFrame:)]) { + self.shouldObserveVisibility= YES; + } return self; } @@ -57,6 +60,9 @@ [self addSubnode:_viewControllerNode]; } + if ([self.layoutDelegate respondsToSelector:@selector(visibleNodeDidScroll:inScrollView:withCellFrame:)]) { + self.shouldObserveVisibility = YES; + } return self; } @@ -134,6 +140,20 @@ [(_ASDisplayView *)self.view __forwardTouchesCancelled:touches withEvent:event]; } +<<<<<<< HEAD +- (void)updateScrollSituationWithScrollVIew:(UIScrollView *)scrollView +{ + // TODO(Max): Fix the cellFrame here + [self.layoutDelegate scrollViewDidScroll:scrollView cellFrameInScrollView:CGRectZero]; +======= +- (void)_visibleNodeDidScroll:(UIScrollView *)scrollView withCellFrame:(CGRect)cellFrame +{ + if (layoutDelegateImplementsVisibleNodeDidScroll) { + [self.layoutDelegate visibleNodeDidScroll:self inScrollView:scrollView withCellFrame:cellFrame]; + } +>>>>>>> 4b8216f... Adding scroll visibility +} + @end diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index b9f58ee5ff..cd31312cb9 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -9,6 +9,7 @@ #import "ASAssert.h" #import "ASBatchFetching.h" #import "ASDelegateProxy.h" +#import "ASCellNode+Internal.h" #import "ASCollectionNode.h" #import "ASCollectionDataController.h" #import "ASCollectionViewLayoutController.h" @@ -67,7 +68,11 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; ASRangeController *_rangeController; ASCollectionViewLayoutController *_layoutController; ASCollectionViewFlowLayoutInspector *_flowLayoutInspector; - +<<<<<<< HEAD + NSMutableArray *_cellsForVisibilityUpdates; +======= + NSMutableSet *_cellsForVisibilityUpdates; +>>>>>>> 4b8216f... Adding scroll visibility id _layoutFacilitator; BOOL _performingBatchUpdates; @@ -75,6 +80,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; BOOL _asyncDataFetchingEnabled; BOOL _asyncDelegateImplementsInsetSection; + BOOL _asyncDelegateImplementsScrollviewDidScroll; BOOL _collectionViewLayoutImplementsInsetSection; BOOL _asyncDataSourceImplementsConstrainedSizeForNode; BOOL _asyncDataSourceImplementsNodeBlockForItemAtIndexPath; @@ -212,6 +218,11 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; _registeredSupplementaryKinds = [NSMutableSet set]; +<<<<<<< HEAD + _cellsForVisibilityUpdates = [[NSMutableArray alloc] init]; +======= + _cellsForVisibilityUpdates = [NSMutableSet set]; +>>>>>>> 4b8216f... Adding scroll visibility self.backgroundColor = [UIColor whiteColor]; [self registerClass:[_ASCollectionViewCell class] forCellWithReuseIdentifier:kCellReuseIdentifier]; @@ -328,12 +339,14 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; _asyncDelegate = nil; _proxyDelegate = _isDeallocating ? nil : [[ASCollectionViewProxy alloc] initWithTarget:nil interceptor:self]; _asyncDelegateImplementsInsetSection = NO; + _asyncDelegateImplementsScrollviewDidScroll = NO; } else { _asyncDelegate = asyncDelegate; _proxyDelegate = [[ASCollectionViewProxy alloc] initWithTarget:_asyncDelegate interceptor:self]; _asyncDelegateImplementsInsetSection = ([_asyncDelegate respondsToSelector:@selector(collectionView:layout:insetForSectionAtIndex:)] ? 1 : 0); + _asyncDelegateImplementsScrollviewDidScroll = ([_asyncDelegate respondsToSelector:@selector(scrollViewDidScroll:)] ? 1 : 0); } - + super.delegate = (id)_proxyDelegate; [_layoutInspector didChangeCollectionViewDelegate:asyncDelegate]; @@ -589,6 +602,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; if (cellNode.neverShowPlaceholders) { [cellNode recursivelyEnsureDisplaySynchronously:YES]; } + [_cellsForVisibilityUpdates addObject:cell]; } - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath @@ -600,6 +614,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; ASDisplayNodeAssertNotNil(node, @"Expected node associated with removed cell not to be nil."); [_asyncDelegate collectionView:self didEndDisplayingNode:node forItemAtIndexPath:indexPath]; } + [_cellsForVisibilityUpdates removeObject:cell]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" if ([_asyncDelegate respondsToSelector:@selector(collectionView:didEndDisplayingNodeForItemAtIndexPath:)]) { @@ -650,6 +665,30 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; } } +<<<<<<< HEAD +- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ + for (ASCellNode *node in _cellsForVisibilityUpdates) { + if (node.shouldObserveVisibility) { + [node updateScrollSituationWithScrollVIew:scrollView]; + } + } + if ([_asyncDelegate respondsToSelector:@selector(scrollViewDidScroll:)]) { + [_asyncDelegate scrollViewDidScroll:scrollView]; + } +======= +- (void)scrollViewDidScroll:(UIScrollView *)scrollView +{ + for (ASCellNode *node in _cellsForVisibilityUpdates) { + if (node.shouldObserveVisibility) { + [node _visibleNodeDidScroll:scrollView withCellFrame:node.frame]; + } + } + if (_asyncDelegateImplementsScrollviewDidScroll) { + [_asyncDelegate scrollViewDidScroll:scrollView]; + } +>>>>>>> 4b8216f... Adding scroll visibility +} + - (BOOL)shouldBatchFetch { // if the delegate does not respond to this method, there is no point in starting to fetch diff --git a/AsyncDisplayKit/Details/ASDelegateProxy.m b/AsyncDisplayKit/Details/ASDelegateProxy.m index 2af0e7c7d5..baa65a65c7 100644 --- a/AsyncDisplayKit/Details/ASDelegateProxy.m +++ b/AsyncDisplayKit/Details/ASDelegateProxy.m @@ -56,6 +56,9 @@ // used for batch fetching API selector == @selector(scrollViewWillEndDragging:withVelocity:targetContentOffset:) || + // used for ASCellNode visibility + selector == @selector(scrollViewDidScroll:) || + // intercepted due to not being supported by ASCollectionView (prevent bugs caused by usage) selector == @selector(collectionView:canMoveItemAtIndexPath:) || selector == @selector(collectionView:moveItemAtIndexPath:toIndexPath:) ||