-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Improve cell node relayout #793
Changes from all commits
cd31f88
00400e1
c7d18a4
5b8f7e9
fb18e76
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ | |
|
|
||
| #import "ASCellNode.h" | ||
|
|
||
| #import "ASInternalHelpers.h" | ||
| #import <AsyncDisplayKit/_ASDisplayView.h> | ||
| #import <AsyncDisplayKit/ASDisplayNode+Subclasses.h> | ||
| #import <AsyncDisplayKit/ASTextNode.h> | ||
|
|
@@ -27,6 +28,7 @@ - (instancetype)init | |
| // use UITableViewCell defaults | ||
| _selectionStyle = UITableViewCellSelectionStyleDefault; | ||
| self.clipsToBounds = YES; | ||
| _relayoutAnimation = UITableViewRowAnimationAutomatic; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the purpose of having a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It can be set to another value, by another object or in the subclass's initializer. |
||
|
|
||
| return self; | ||
| } | ||
|
|
@@ -49,6 +51,18 @@ - (void)setLayerBacked:(BOOL)layerBacked | |
| ASDisplayNodeAssert(!layerBacked, @"ASCellNode does not support layer-backing."); | ||
| } | ||
|
|
||
| - (void)setNeedsLayout | ||
| { | ||
| ASDisplayNodeAssertThreadAffinity(self); | ||
| [super setNeedsLayout]; | ||
|
|
||
| if (_delegate != nil) { | ||
| ASPerformBlockOnMainThread(^{ | ||
| [_delegate node:self didRelayoutWithSuggestedAnimation:_relayoutAnimation]; | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event | ||
| { | ||
| ASDisplayNodeAssertMainThread(); | ||
|
|
@@ -122,7 +136,7 @@ - (void)setText:(NSString *)text | |
| _text = [text copy]; | ||
| _textNode.attributedString = [[NSAttributedString alloc] initWithString:_text | ||
| attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:kFontSize]}]; | ||
|
|
||
| [self setNeedsLayout]; | ||
| } | ||
|
|
||
| @end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,7 +12,6 @@ | |
| #import "ASCollectionViewLayoutController.h" | ||
| #import "ASRangeController.h" | ||
| #import "ASCollectionDataController.h" | ||
| #import "ASDisplayNodeInternal.h" | ||
| #import "ASBatchFetching.h" | ||
| #import "UICollectionViewLayout+ASConvenience.h" | ||
| #import "ASInternalHelpers.h" | ||
|
|
@@ -131,7 +130,7 @@ - (void)setHighlighted:(BOOL)highlighted | |
| #pragma mark - | ||
| #pragma mark ASCollectionView. | ||
|
|
||
| @interface ASCollectionView () <ASRangeControllerDelegate, ASDataControllerSource> { | ||
| @interface ASCollectionView () <ASRangeControllerDelegate, ASDataControllerSource, ASCellNodeDelegate> { | ||
| _ASCollectionViewProxy *_proxyDataSource; | ||
| _ASCollectionViewProxy *_proxyDelegate; | ||
|
|
||
|
|
@@ -269,7 +268,7 @@ - (ASCollectionViewFlowLayoutInspector *)flowLayoutInspector | |
| - (void)reloadDataWithCompletion:(void (^)())completion | ||
| { | ||
| ASDisplayNodeAssert(self.asyncDelegate, @"ASCollectionView's asyncDelegate property must be set."); | ||
| ASDisplayNodePerformBlockOnMainThread(^{ | ||
| ASPerformBlockOnMainThread(^{ | ||
| _superIsPendingDataLoad = YES; | ||
| [super reloadData]; | ||
| }); | ||
|
|
@@ -458,14 +457,6 @@ - (void)reloadItemsAtIndexPaths:(NSArray *)indexPaths | |
| [_dataController reloadRowsAtIndexPaths:indexPaths withAnimationOptions:kASCollectionViewAnimationNone]; | ||
| } | ||
|
|
||
| - (void)relayoutItemAtIndexPath:(NSIndexPath *)indexPath | ||
| { | ||
| ASDisplayNodeAssertMainThread(); | ||
| ASCellNode *node = [self nodeForItemAtIndexPath:indexPath]; | ||
| [node setNeedsLayout]; | ||
| [super reloadItemsAtIndexPaths:@[indexPath]]; | ||
| } | ||
|
|
||
| - (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath | ||
| { | ||
| ASDisplayNodeAssertMainThread(); | ||
|
|
@@ -664,6 +655,7 @@ - (ASCellNode *)dataController:(ASDataController *)dataController nodeAtIndexPat | |
| { | ||
| ASCellNode *node = [_asyncDataSource collectionView:self nodeForItemAtIndexPath:indexPath]; | ||
| ASDisplayNodeAssert([node isKindOfClass:ASCellNode.class], @"invalid node class, expected ASCellNode"); | ||
| node.delegate = self; | ||
| return node; | ||
| } | ||
|
|
||
|
|
@@ -907,4 +899,15 @@ - (void)rangeController:(ASRangeController *)rangeController didDeleteSectionsAt | |
| } | ||
| } | ||
|
|
||
| #pragma mark - ASCellNodeDelegate | ||
|
|
||
| - (void)node:(ASCellNode *)node didRelayoutWithSuggestedAnimation:(ASCellNodeAnimation)animation | ||
| { | ||
| ASDisplayNodeAssertMainThread(); | ||
| NSIndexPath *indexPath = [self indexPathForNode:node]; | ||
| if (indexPath != nil) { | ||
| [super reloadItemsAtIndexPaths:@[indexPath]]; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if there's a way to coalesce these without limiting the ability to wrap in animation blocks. Maybe it's not an issue, but do you see visually sequential loading / flashing if you set multiple cells as needing layout? Even if there were a longer delay due to main thread measurement, it would be best for all of those to happen together.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After the changes in #812, it's up to the developer the animate the layout changes in multiple cells, i.e they can wrap multiple |
||
| } | ||
| } | ||
|
|
||
| @end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -559,14 +559,6 @@ typedef void (^ASDisplayNodeDidLoadBlock)(ASDisplayNode *node); | |
| * | ||
| * If this node was measured, calling this method triggers an internal relayout: the calculated layout is invalidated, | ||
| * and the supernode is notified or (if this node is the root one) a full measurement pass is executed using the old constrained size. | ||
| * | ||
| * Note: If the relayout causes a change in size of the root node that is attached to a container view, | ||
| * the container view must be notified to relayout. | ||
| * For ASTableView and ASCollectionView, instead of calling this method directly, | ||
| * it is recommended to call -relayoutRowAtIndexPath:withRowAnimation and -relayoutItemAtIndexPath: respectively. | ||
| * | ||
| * @see [ASTableView relayoutRowAtIndexPath:withRowAnimation:] | ||
| * @see [ASCollectionView relayoutItemAtIndexPath:] | ||
| */ | ||
| - (void)setNeedsLayout; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would replace this with something like "Note: ASCellNode has special behavior in that calling this method will automatically notify the containing ASTableView / ASCollectionView that the cell should be resized, if necessary."
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added in #812. Thanks. |
||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's only safe to call from the background if the node isn't loaded, right? We should probably just remove that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in #812.