From 75eab1db07382d33598b082b27e65833dd65cc08 Mon Sep 17 00:00:00 2001 From: Max Gu Date: Thu, 18 Feb 2016 18:00:37 -0800 Subject: [PATCH] Adding scroll visibility --- AsyncDisplayKit/ASCellNode.h | 5 +++++ AsyncDisplayKit/ASCellNode.m | 6 ++++++ AsyncDisplayKit/ASCollectionView.mm | 16 +++++++++++++++- AsyncDisplayKit/Details/ASDelegateProxy.m | 3 +++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/AsyncDisplayKit/ASCellNode.h b/AsyncDisplayKit/ASCellNode.h index d1e575383e..669c6757f5 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,8 @@ typedef NSUInteger ASCellNodeAnimation; * @param sizeChanged `YES` if the node's `calculatedSize` changed during the relayout, `NO` otherwise. */ - (void)nodeDidRelayout:(ASCellNode *)node sizeChanged:(BOOL)sizeChanged; + + @end /** @@ -75,6 +78,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 +111,7 @@ typedef NSUInteger ASCellNodeAnimation; */ - (instancetype)initWithViewControllerBlock:(ASDisplayNodeViewControllerBlock)viewControllerBlock didLoadBlock:(ASDisplayNodeDidLoadBlock)didLoadBlock; +- (void)updateScrollSituationWithScrollVIew:(UIScrollView *)scrollView; @end diff --git a/AsyncDisplayKit/ASCellNode.m b/AsyncDisplayKit/ASCellNode.m index df7040d92e..840c5edea3 100644 --- a/AsyncDisplayKit/ASCellNode.m +++ b/AsyncDisplayKit/ASCellNode.m @@ -134,6 +134,12 @@ [(_ASDisplayView *)self.view __forwardTouchesCancelled:touches withEvent:event]; } +- (void)updateScrollSituationWithScrollVIew:(UIScrollView *)scrollView +{ + // TODO(Max): Fix the cellFrame here + [self.layoutDelegate scrollViewDidScroll:scrollView cellFrameInScrollView:CGRectZero]; +} + @end diff --git a/AsyncDisplayKit/ASCollectionView.mm b/AsyncDisplayKit/ASCollectionView.mm index b9f58ee5ff..ccfaa73115 100644 --- a/AsyncDisplayKit/ASCollectionView.mm +++ b/AsyncDisplayKit/ASCollectionView.mm @@ -67,7 +67,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; ASRangeController *_rangeController; ASCollectionViewLayoutController *_layoutController; ASCollectionViewFlowLayoutInspector *_flowLayoutInspector; - + NSMutableArray *_cellsForVisibilityUpdates; id _layoutFacilitator; BOOL _performingBatchUpdates; @@ -212,6 +212,7 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; _registeredSupplementaryKinds = [NSMutableSet set]; + _cellsForVisibilityUpdates = [[NSMutableArray alloc] init]; self.backgroundColor = [UIColor whiteColor]; [self registerClass:[_ASCollectionViewCell class] forCellWithReuseIdentifier:kCellReuseIdentifier]; @@ -589,6 +590,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 +602,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 +653,17 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell"; } } +- (void)scrollViewDidScroll:(UIScrollView *)scrollView{ + for (ASCellNode *node in _cellsForVisibilityUpdates) { + if (node.shouldObserveVisibility) { + [node updateScrollSituationWithScrollVIew:scrollView]; + } + } + if ([_asyncDelegate respondsToSelector:@selector(scrollViewDidScroll:)]) { + [_asyncDelegate scrollViewDidScroll:scrollView]; + } +} + - (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:) ||