mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-12 09:19:52 +00:00
Introduce ASCellNodeDelegate
- Cell node automatically notifies the delegate after a relayout (via -setNeedsLayout) that results in a new size. Confirming to ASCellNodeDelegate; ASTableView and ASCollectionView reload the calling cell upon notifications. These views automatically set themselves as delegate of every node. - The result is that ASCellNode subclasses don't need to manually notify the containing view. Thus, `-relayoutItemAtIndexPath` and `-relayoutRowAtIndexPath` are removed. - Kittens example is updated to reflect the change.
This commit is contained in:
parent
cd31f884dd
commit
00400e166f
@ -8,6 +8,24 @@
|
||||
|
||||
#import <AsyncDisplayKit/ASDisplayNode.h>
|
||||
|
||||
@class ASCellNode;
|
||||
|
||||
typedef NSUInteger ASCellNodeAnimation;
|
||||
|
||||
@protocol ASCellNodeDelegate <NSObject>
|
||||
|
||||
/**
|
||||
* Notifies the delegate that the specified cell node has done a relayout that results in a new size.
|
||||
* The notification is done on main thread.
|
||||
*
|
||||
* @param node A node informing the delegate about the relayout.
|
||||
*
|
||||
* @param newSize A new size that is resulted in the relayout.
|
||||
*
|
||||
* @param suggestedAnimation A constant that indicates how the delegate should animate. See UITableViewRowAnimation.
|
||||
*/
|
||||
- (void)node:(ASCellNode *)node didRelayoutToNewSize:(CGSize)newSize suggestedAnimation:(ASCellNodeAnimation)animation;
|
||||
@end
|
||||
|
||||
/**
|
||||
* Generic cell node. Subclass this instead of `ASDisplayNode` to use with `ASTableView` and `ASCollectionView`.
|
||||
@ -53,6 +71,18 @@
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL highlighted;
|
||||
|
||||
/*
|
||||
* A delegate to be notified (on main thread) after a relayout that results in a new size.
|
||||
*/
|
||||
@property (nonatomic, weak) id<ASCellNodeDelegate> delegate;
|
||||
|
||||
/*
|
||||
* A constant that is passed to the delegate to indicate how a relayout is to be animated.
|
||||
*
|
||||
* @see UITableViewRowAnimation
|
||||
*/
|
||||
@property (nonatomic, assign) ASCellNodeAnimation relayoutAnimation;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
@ -62,6 +92,16 @@
|
||||
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event ASDISPLAYNODE_REQUIRES_SUPER;
|
||||
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event ASDISPLAYNODE_REQUIRES_SUPER;
|
||||
|
||||
/**
|
||||
* Marks the node as needing layout. Convenience for use whether the view / layer is loaded or not. Safe to call from a background thread.
|
||||
*
|
||||
* 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, the delegate will be notified (on main thread) to relayout.
|
||||
*/
|
||||
- (void)setNeedsLayout;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@ -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 @@
|
||||
// use UITableViewCell defaults
|
||||
_selectionStyle = UITableViewCellSelectionStyleDefault;
|
||||
self.clipsToBounds = YES;
|
||||
_relayoutAnimation = UITableViewRowAnimationAutomatic;
|
||||
|
||||
return self;
|
||||
}
|
||||
@ -49,6 +51,21 @@
|
||||
ASDisplayNodeAssert(!layerBacked, @"ASCellNode does not support layer-backing.");
|
||||
}
|
||||
|
||||
- (void)setNeedsLayout
|
||||
{
|
||||
ASDisplayNodeAssertThreadAffinity(self);
|
||||
|
||||
CGSize oldSize = self.calculatedSize;
|
||||
[super setNeedsLayout];
|
||||
CGSize newSize = self.calculatedSize;
|
||||
|
||||
if (_delegate != nil && !CGSizeEqualToSize(oldSize, newSize)) {
|
||||
ASPerformBlockOnMainThread(^{
|
||||
[_delegate node:self didRelayoutToNewSize:newSize suggestedAnimation:_relayoutAnimation];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
|
||||
@ -223,16 +223,6 @@
|
||||
*/
|
||||
- (void)reloadItemsAtIndexPaths:(NSArray *)indexPaths;
|
||||
|
||||
/**
|
||||
* Relayouts the specified item.
|
||||
*
|
||||
* @param indexPath The index path identifying the item to relayout.
|
||||
*
|
||||
* @discussion This method must be called from the main thread. The relayout is excuted on main thread.
|
||||
* The node of the specified item must be updated to cause layout changes before this method is called.
|
||||
*/
|
||||
- (void)relayoutItemAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
/**
|
||||
* Moves the item at a specified location to a destination location.
|
||||
*
|
||||
|
||||
@ -130,7 +130,7 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
#pragma mark -
|
||||
#pragma mark ASCollectionView.
|
||||
|
||||
@interface ASCollectionView () <ASRangeControllerDelegate, ASDataControllerSource> {
|
||||
@interface ASCollectionView () <ASRangeControllerDelegate, ASDataControllerSource, ASCellNodeDelegate> {
|
||||
_ASCollectionViewProxy *_proxyDataSource;
|
||||
_ASCollectionViewProxy *_proxyDelegate;
|
||||
|
||||
@ -457,14 +457,6 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
[_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();
|
||||
@ -663,6 +655,7 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
{
|
||||
ASCellNode *node = [_asyncDataSource collectionView:self nodeForItemAtIndexPath:indexPath];
|
||||
ASDisplayNodeAssert([node isKindOfClass:ASCellNode.class], @"invalid node class, expected ASCellNode");
|
||||
node.delegate = self;
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -906,4 +899,15 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - ASCellNodeDelegate
|
||||
|
||||
- (void)node:(ASCellNode *)node didRelayoutToNewSize:(CGSize)newSize suggestedAnimation:(ASCellNodeAnimation)animation
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
NSIndexPath *indexPath = [self indexPathForNode:node];
|
||||
if (indexPath != nil) {
|
||||
[super reloadItemsAtIndexPaths:@[indexPath]];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -214,18 +214,6 @@
|
||||
*/
|
||||
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
|
||||
|
||||
/**
|
||||
* Relayouts the specified row using a given animation effect.
|
||||
*
|
||||
* @param indexPath The index path identifying the row to relayout.
|
||||
*
|
||||
* @param animation A constant that indicates how the relayout is to be animated. See UITableViewRowAnimation.
|
||||
*
|
||||
* @discussion This method must be called from the main thread. The relayout is excuted on main thread.
|
||||
* The node of the specified row must be updated to cause layout changes before this method is called.
|
||||
*/
|
||||
- (void)relayoutRowAtIndexPath:(NSIndexPath *)indexPath withRowAnimation:(UITableViewRowAnimation)animation;
|
||||
|
||||
/**
|
||||
* Moves the row at a specified location to a destination location.
|
||||
*
|
||||
|
||||
@ -151,7 +151,7 @@ static BOOL _isInterceptedSelector(SEL sel)
|
||||
#pragma mark -
|
||||
#pragma mark ASTableView
|
||||
|
||||
@interface ASTableView () <ASRangeControllerDelegate, ASDataControllerSource, _ASTableViewCellDelegate> {
|
||||
@interface ASTableView () <ASRangeControllerDelegate, ASDataControllerSource, _ASTableViewCellDelegate, ASCellNodeDelegate> {
|
||||
_ASTableViewProxy *_proxyDataSource;
|
||||
_ASTableViewProxy *_proxyDelegate;
|
||||
|
||||
@ -476,14 +476,6 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
|
||||
[_dataController reloadRowsAtIndexPaths:indexPaths withAnimationOptions:animation];
|
||||
}
|
||||
|
||||
- (void)relayoutRowAtIndexPath:(NSIndexPath *)indexPath withRowAnimation:(UITableViewRowAnimation)animation
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASCellNode *node = [self nodeForRowAtIndexPath:indexPath];
|
||||
[node setNeedsLayout];
|
||||
[super reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:animation];
|
||||
}
|
||||
|
||||
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
@ -848,6 +840,7 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
|
||||
{
|
||||
ASCellNode *node = [_asyncDataSource tableView:self nodeForRowAtIndexPath:indexPath];
|
||||
ASDisplayNodeAssert([node isKindOfClass:ASCellNode.class], @"invalid node class, expected ASCellNode");
|
||||
node.delegate = self;
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -922,4 +915,15 @@ void ASPerformBlockWithoutAnimation(BOOL withoutAnimation, void (^block)()) {
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - ASCellNodeDelegate
|
||||
|
||||
- (void)node:(ASCellNode *)node didRelayoutToNewSize:(CGSize)newSize suggestedAnimation:(ASCellNodeAnimation)animation
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
NSIndexPath *indexPath = [self indexPathForNode:node];
|
||||
if (indexPath != nil) {
|
||||
[super reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:(UITableViewRowAnimation)animation];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -185,6 +185,7 @@ static const CGFloat kInnerPadding = 10.0f;
|
||||
- (void)toggleImageEnlargement
|
||||
{
|
||||
_isImageEnlarged = !_isImageEnlarged;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)toggleNodesSwap
|
||||
|
||||
@ -121,7 +121,6 @@ static const NSInteger kMaxLitterSize = 100; // max number of kitten cell
|
||||
// Assume only kitten nodes are selectable (see -tableView:shouldHighlightRowAtIndexPath:).
|
||||
KittenNode *node = (KittenNode *)[_tableView nodeForRowAtIndexPath:indexPath];
|
||||
[node toggleImageEnlargement];
|
||||
[_tableView relayoutRowAtIndexPath:indexPath withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
}
|
||||
|
||||
- (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user