mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-20 13:19:16 +00:00
Some more changes
This commit is contained in:
parent
c819d716b4
commit
0eb882bae5
@ -29,7 +29,7 @@
|
||||
#pragma mark -
|
||||
#pragma mark ASCellNode
|
||||
|
||||
@interface ASCellNode () <ASDisplayNodeSizingDelegate>
|
||||
@interface ASCellNode ()
|
||||
{
|
||||
ASDisplayNodeViewControllerBlock _viewControllerBlock;
|
||||
ASDisplayNodeDidLoadBlock _viewControllerDidLoadBlock;
|
||||
@ -58,9 +58,6 @@ static NSMutableSet *__cellClassesForVisibilityNotifications = nil; // See +init
|
||||
// Use UITableViewCell defaults
|
||||
_selectionStyle = UITableViewCellSelectionStyleDefault;
|
||||
self.clipsToBounds = YES;
|
||||
|
||||
// ASCellNode acts as sizing container for the node
|
||||
self.sizingDelegate = self;
|
||||
|
||||
return self;
|
||||
}
|
||||
@ -121,19 +118,16 @@ static NSMutableSet *__cellClassesForVisibilityNotifications = nil; // See +init
|
||||
_viewControllerNode.frame = self.bounds;
|
||||
}
|
||||
|
||||
- (void)displayNodeDidInvalidateSize:(ASDisplayNode *)displayNode
|
||||
- (void)didInvalidateSize
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
// TODO: coalesc: Ask the UITableView for the proper constrained size it can layout
|
||||
CGSize oldSize = self.calculatedSize;
|
||||
CGSize newSize = [self sizeThatFits:CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX)];
|
||||
|
||||
CGSize oldSize = self.calculatedSize;
|
||||
ASLayout *layout = [self layoutThatFits:self.constrainedSizeForCalculatedLayout];
|
||||
|
||||
// TODO: Needs proper adjustment
|
||||
CGRect f = self.frame;
|
||||
f.size = layout.size;
|
||||
self.frame = f;
|
||||
|
||||
[self didRelayoutFromOldSize:oldSize toNewSize:layout.size];
|
||||
if (CGSizeEqualToSize(oldSize, newSize) == NO) {
|
||||
self.frame = {self.frame.origin, newSize};
|
||||
[self didRelayoutFromOldSize:oldSize toNewSize:newSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)transitionLayoutWithAnimation:(BOOL)animated
|
||||
|
||||
@ -765,7 +765,9 @@ static NSString * const kCellReuseIdentifier = @"_ASCollectionViewCell";
|
||||
|
||||
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return [[self nodeForItemAtIndexPath:indexPath] calculatedSize];
|
||||
ASDisplayNode *node = [self nodeForItemAtIndexPath:indexPath];
|
||||
[node layoutIfNeeded];
|
||||
return node.calculatedSize;
|
||||
}
|
||||
|
||||
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
|
||||
@ -267,8 +267,9 @@ extern NSInteger const ASDefaultDrawingPriority;
|
||||
|
||||
/** @name Managing dimensions */
|
||||
|
||||
@property (nonatomic, readwrite, weak, nullable) id<ASDisplayNodeSizingDelegate> sizingDelegate;
|
||||
//@property (nonatomic, readwrite, weak, nullable) id<ASDisplayNodeSizingDelegate> sizingDelegate;
|
||||
- (void)invalidateSize;
|
||||
- (void)didInvalidateSize;
|
||||
- (void)sizeToFit;
|
||||
|
||||
- (CGSize)sizeThatFits:(CGSize)size;
|
||||
|
||||
@ -709,14 +709,18 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
|
||||
__instanceLock__.lock();
|
||||
|
||||
// Mark the node for layout in the next layout pass
|
||||
[self invalidateCalculatedLayout];
|
||||
|
||||
// This is the root node. Let the delegate know that the size changed
|
||||
// If someone calls `invalidateBlaBla TBD` we have to inform the sizing delegate of the root node to be able
|
||||
// to let them now that a size change happened and it needs to calculate a new layout / size for this node hierarchy
|
||||
if ([self.sizingDelegate respondsToSelector:@selector(displayNodeDidInvalidateSize:)]) {
|
||||
[self.sizingDelegate displayNodeDidInvalidateSize:self];
|
||||
}
|
||||
// if ([self.sizingDelegate respondsToSelector:@selector(displayNodeDidInvalidateSize:)]) {
|
||||
// [self.sizingDelegate displayNodeDidInvalidateSize:self];
|
||||
// }
|
||||
|
||||
// Hook for subclasses to get size invalidation changes
|
||||
[self didInvalidateSize];
|
||||
|
||||
if (_supernode) {
|
||||
ASDisplayNode *supernode = _supernode;
|
||||
@ -727,9 +731,17 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
return;
|
||||
}
|
||||
|
||||
// We are now at the root node trigger a layout pass
|
||||
[self setNeedsLayout];
|
||||
|
||||
__instanceLock__.unlock();
|
||||
}
|
||||
|
||||
- (void)didInvalidateSize
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
- (void)sizeToFit
|
||||
{
|
||||
ASDisplayNodeAssertThreadAffinity(self);
|
||||
@ -739,11 +751,10 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
[self setNeedsLayout];
|
||||
|
||||
CGSize maxSize = _supernode ? _supernode.bounds.size : CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);
|
||||
CGSize size = [self sizeThatFits:maxSize];
|
||||
CGSize newSize = [self sizeThatFits:maxSize];
|
||||
|
||||
CGRect oldBounds = self.bounds;
|
||||
CGSize oldSize = oldBounds.size;
|
||||
CGSize newSize = _calculatedDisplayNodeLayout->layout.size;
|
||||
|
||||
if (! CGSizeEqualToSize(oldSize, newSize)) {
|
||||
self.bounds = (CGRect){ oldBounds.origin, newSize };
|
||||
@ -777,74 +788,12 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
|
||||
if ([self shouldCalculateLayoutWithConstrainedSize:constrainedSize parentSize:parentSize] == NO) {
|
||||
if (_calculatedDisplayNodeLayout->isValidForConstrainedSizeParentSize(constrainedSize, parentSize)) {
|
||||
ASDisplayNodeAssertNotNil(_calculatedDisplayNodeLayout->layout, @"-[ASDisplayNode layoutThatFits:parentSize:] _layout should not be nil! %@", self);
|
||||
return _calculatedDisplayNodeLayout->layout ? : [ASLayout layoutWithLayoutElement:self size:{0, 0}];
|
||||
}
|
||||
|
||||
[self cancelLayoutTransition];
|
||||
|
||||
BOOL didCreateNewContext = NO;
|
||||
BOOL didOverrideExistingContext = NO;
|
||||
BOOL shouldVisualizeLayout = ASHierarchyStateIncludesVisualizeLayout(_hierarchyState);
|
||||
ASLayoutElementContext context;
|
||||
if (ASLayoutElementContextIsNull(ASLayoutElementGetCurrentContext())) {
|
||||
context = ASLayoutElementContextMake(ASLayoutElementContextDefaultTransitionID, shouldVisualizeLayout);
|
||||
ASLayoutElementSetCurrentContext(context);
|
||||
didCreateNewContext = YES;
|
||||
} else {
|
||||
context = ASLayoutElementGetCurrentContext();
|
||||
if (context.needsVisualizeNode != shouldVisualizeLayout) {
|
||||
context.needsVisualizeNode = shouldVisualizeLayout;
|
||||
ASLayoutElementSetCurrentContext(context);
|
||||
didOverrideExistingContext = YES;
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare for layout transition
|
||||
auto previousLayout = _calculatedDisplayNodeLayout;
|
||||
auto pendingLayout = std::make_shared<ASDisplayNodeLayout>(
|
||||
[self calculateLayoutThatFits:constrainedSize restrictedToSize:self.style.size relativeToParentSize:parentSize],
|
||||
constrainedSize,
|
||||
parentSize
|
||||
);
|
||||
|
||||
if (didCreateNewContext) {
|
||||
ASLayoutElementClearCurrentContext();
|
||||
} else if (didOverrideExistingContext) {
|
||||
context.needsVisualizeNode = !context.needsVisualizeNode;
|
||||
ASLayoutElementSetCurrentContext(context);
|
||||
}
|
||||
|
||||
_pendingLayoutTransition = [[ASLayoutTransition alloc] initWithNode:self
|
||||
pendingLayout:pendingLayout
|
||||
previousLayout:previousLayout];
|
||||
|
||||
// Only complete the pending layout transition if the node is not a subnode of a node that is currently
|
||||
// in a layout transition
|
||||
if (ASHierarchyStateIncludesLayoutPending(_hierarchyState) == NO) {
|
||||
// Complete the pending layout transition immediately
|
||||
[self _completePendingLayoutTransition];
|
||||
}
|
||||
|
||||
ASDisplayNodeAssertNotNil(pendingLayout->layout, @"-[ASDisplayNode layoutThatFits:parentSize:] newLayout should not be nil! %@", self);
|
||||
return pendingLayout->layout;
|
||||
}
|
||||
|
||||
- (BOOL)shouldCalculateLayoutWithConstrainedSize:(ASSizeRange)constrainedSize parentSize:(CGSize)parentSize
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
|
||||
// Don't remeasure if in layout pending state and a new transition already started
|
||||
if (ASHierarchyStateIncludesLayoutPending(_hierarchyState)) {
|
||||
ASLayoutElementContext context = ASLayoutElementGetCurrentContext();
|
||||
if (ASLayoutElementContextIsNull(context) || _pendingTransitionID != context.transitionID) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if display node layout is still valid
|
||||
return _calculatedDisplayNodeLayout->isValidForConstrainedSizeParentSize(constrainedSize, parentSize) == NO;
|
||||
|
||||
return [self calculateLayoutThatFits:constrainedSize restrictedToSize:self.style.size relativeToParentSize:parentSize];
|
||||
}
|
||||
|
||||
- (ASLayoutElementType)layoutElementType
|
||||
@ -883,7 +832,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
return;
|
||||
}
|
||||
|
||||
[self invalidateCalculatedLayout];
|
||||
[self setNeedsLayout];
|
||||
[self transitionLayoutWithSizeRange:_calculatedDisplayNodeLayout->constrainedSize
|
||||
animated:animated
|
||||
shouldMeasureAsync:shouldMeasureAsync
|
||||
@ -898,7 +847,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
{
|
||||
// Passed constrainedSize is the the same as the node's current constrained size it's a noop
|
||||
ASDisplayNodeAssertMainThread();
|
||||
if ([self shouldCalculateLayoutWithConstrainedSize:constrainedSize parentSize:constrainedSize.max] == NO) {
|
||||
if (_calculatedDisplayNodeLayout->isValidForConstrainedSizeParentSize(constrainedSize, constrainedSize.max)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1449,13 +1398,18 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
[self displayImmediately];
|
||||
}
|
||||
|
||||
- (void)invalidateCalculatedLayout
|
||||
{
|
||||
// This will cause the next layout pass to compute a new layout instead of returning
|
||||
// the cached layout in case the constrained or parent size did not change
|
||||
_calculatedDisplayNodeLayout->invalidate();
|
||||
}
|
||||
|
||||
- (void)__setNeedsLayout
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
|
||||
// This will cause the next call to -layoutThatFits:parentSize: to compute a new layout instead of returning
|
||||
// the cached layout in case the constrained or parent size did not change
|
||||
_calculatedDisplayNodeLayout->invalidate();
|
||||
[self invalidateCalculatedLayout];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1482,7 +1436,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
[supernode __layoutIfNeeded];
|
||||
} else {
|
||||
// Layout all subviews starting from the first node that needs layout
|
||||
[self __layout];
|
||||
[self __layoutSublayers];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1498,13 +1452,11 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
|
||||
// These private methods ensure that subclasses are not required to call super in order for _renderingSubnodes to be properly managed.
|
||||
|
||||
- (void)__layout
|
||||
- (void)__layoutSublayers
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
CGRect bounds = self.bounds;
|
||||
|
||||
[self measureNodeWithBoundsIfNecessary:bounds];
|
||||
CGRect bounds = _threadSafeBounds;
|
||||
|
||||
if (CGRectEqualToRect(bounds, CGRectZero)) {
|
||||
// Performing layout on a zero-bounds view often results in frame calculations
|
||||
@ -1512,6 +1464,8 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
// measureWithSizeRange: on subnodes to assert.
|
||||
return;
|
||||
}
|
||||
|
||||
[self measureNodeWithBoundsIfNecessary:bounds];
|
||||
|
||||
// Handle placeholder layer creation in case the size of the node changed after the initial placeholder layer
|
||||
// was created
|
||||
@ -1524,18 +1478,9 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
[self layoutDidFinish];
|
||||
}
|
||||
|
||||
/// Needs to be called with lock held
|
||||
- (void)measureNodeWithBoundsIfNecessary:(CGRect)bounds
|
||||
{
|
||||
BOOL supportsRangeManagedInterfaceState = NO;
|
||||
BOOL hasDirtyLayout = NO;
|
||||
CGSize calculatedLayoutSize = CGSizeZero;
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
supportsRangeManagedInterfaceState = [self supportsRangeManagedInterfaceState];
|
||||
hasDirtyLayout = _calculatedDisplayNodeLayout->isDirty();
|
||||
calculatedLayoutSize = _calculatedDisplayNodeLayout->layout.size;
|
||||
}
|
||||
|
||||
// Check if it's a subnode in a layout transition. In this case no measurement is needed as it's part of
|
||||
// the layout transition
|
||||
if (ASHierarchyStateIncludesLayoutPending(_hierarchyState)) {
|
||||
@ -1549,8 +1494,60 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
// for the node using a size range equal to whatever bounds were provided to the node
|
||||
if (CGRectEqualToRect(bounds, CGRectZero)) {
|
||||
LOG(@"Warning: No size given for node before node was trying to layout itself: %@. Please provide a frame for the node.", self);
|
||||
} else if (hasDirtyLayout || CGSizeEqualToSize(calculatedLayoutSize, bounds.size) == NO) {
|
||||
[self layoutThatFits:ASSizeRangeMake(bounds.size)];
|
||||
return;
|
||||
}
|
||||
|
||||
if (_calculatedDisplayNodeLayout->isDirty() ||
|
||||
CGSizeEqualToSize(_calculatedDisplayNodeLayout->layout.size, bounds.size) == NO)
|
||||
{
|
||||
[self cancelLayoutTransition];
|
||||
|
||||
BOOL didCreateNewContext = NO;
|
||||
BOOL didOverrideExistingContext = NO;
|
||||
BOOL shouldVisualizeLayout = ASHierarchyStateIncludesVisualizeLayout(_hierarchyState);
|
||||
ASLayoutElementContext context;
|
||||
if (ASLayoutElementContextIsNull(ASLayoutElementGetCurrentContext())) {
|
||||
context = ASLayoutElementContextMake(ASLayoutElementContextDefaultTransitionID, shouldVisualizeLayout);
|
||||
ASLayoutElementSetCurrentContext(context);
|
||||
didCreateNewContext = YES;
|
||||
} else {
|
||||
context = ASLayoutElementGetCurrentContext();
|
||||
if (context.needsVisualizeNode != shouldVisualizeLayout) {
|
||||
context.needsVisualizeNode = shouldVisualizeLayout;
|
||||
ASLayoutElementSetCurrentContext(context);
|
||||
didOverrideExistingContext = YES;
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare for layout transition
|
||||
CGSize parentSize = bounds.size;
|
||||
ASSizeRange constrainedSize = ASSizeRangeMake(parentSize);
|
||||
auto previousLayout = _calculatedDisplayNodeLayout;
|
||||
auto pendingLayout = std::make_shared<ASDisplayNodeLayout>(
|
||||
[self calculateLayoutThatFits:constrainedSize restrictedToSize:self.style.size relativeToParentSize:parentSize],
|
||||
constrainedSize,
|
||||
parentSize
|
||||
);
|
||||
|
||||
if (didCreateNewContext) {
|
||||
ASLayoutElementClearCurrentContext();
|
||||
} else if (didOverrideExistingContext) {
|
||||
context.needsVisualizeNode = !context.needsVisualizeNode;
|
||||
ASLayoutElementSetCurrentContext(context);
|
||||
}
|
||||
|
||||
ASDisplayNodeAssertNotNil(pendingLayout->layout, @"pendintLayout->layout should not be nil! %@", self);
|
||||
|
||||
_pendingLayoutTransition = [[ASLayoutTransition alloc] initWithNode:self
|
||||
pendingLayout:pendingLayout
|
||||
previousLayout:previousLayout];
|
||||
|
||||
// Only complete the pending layout transition if the node is not a subnode of a node that is currently
|
||||
// in a layout transition
|
||||
if (ASHierarchyStateIncludesLayoutPending(_hierarchyState) == NO) {
|
||||
// Complete the pending layout transition immediately
|
||||
[self _completePendingLayoutTransition];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2680,15 +2677,6 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)invalidateCalculatedLayout
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
|
||||
// This will cause the next call to -layoutThatFits:parentSize: to compute a new layout instead of returning
|
||||
// the cached layout in case the constrained or parent size did not change
|
||||
_calculatedDisplayNodeLayout->invalidate();
|
||||
}
|
||||
|
||||
- (void)__didLoad
|
||||
{
|
||||
ASDN::MutexLocker l(__instanceLock__);
|
||||
@ -3730,7 +3718,7 @@ static const char *ASDisplayNodeAssociatedNodeKey = "ASAssociatedNode";
|
||||
{
|
||||
// Deprecated preferredFrameSize just calls through to set width and height
|
||||
self.style.preferredSize = preferredFrameSize;
|
||||
[self invalidateCalculatedLayout];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (CGSize)preferredFrameSize
|
||||
|
||||
@ -204,7 +204,7 @@ struct ASImageNodeDrawParameters {
|
||||
if (!ASObjectIsEqual(_image, image)) {
|
||||
_image = image;
|
||||
|
||||
[self invalidateCalculatedLayout];
|
||||
[self setNeedsLayout];
|
||||
if (image) {
|
||||
[self setNeedsDisplay];
|
||||
|
||||
|
||||
@ -751,6 +751,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
ASCellNode *node = [_dataController nodeAtIndexPath:indexPath];
|
||||
[node layoutIfNeeded];
|
||||
return node.calculatedSize.height;
|
||||
}
|
||||
|
||||
@ -1509,8 +1510,6 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
|
||||
#pragma mark - _ASTableViewCellDelegate
|
||||
|
||||
#pragma mark - _ASTableViewCellDelegate
|
||||
|
||||
- (void)didLayoutSubviewsOfTableViewCell:(_ASTableViewCell *)tableViewCell
|
||||
{
|
||||
ASCellNode *node = tableViewCell.node;
|
||||
@ -1525,7 +1524,7 @@ static NSString * const kCellReuseIdentifier = @"_ASTableViewCell";
|
||||
// Normally the content view width equals to the constrained size width (which equals to the table view width).
|
||||
// If there is a mismatch between these values, for example after the table view entered or left editing mode,
|
||||
// content view width is preferred and used to re-measure the cell node.
|
||||
if (contentViewWidth != constrainedSize.max.width) {
|
||||
if (CGSizeEqualToSize(node.calculatedSize, CGSizeZero) == NO && contentViewWidth != constrainedSize.max.width) {
|
||||
constrainedSize.min.width = contentViewWidth;
|
||||
constrainedSize.max.width = contentViewWidth;
|
||||
|
||||
|
||||
@ -330,8 +330,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
BOOL needsUpdate = !UIEdgeInsetsEqualToEdgeInsets(textContainerInset, _textContainerInset);
|
||||
if (needsUpdate) {
|
||||
_textContainerInset = textContainerInset;
|
||||
[self invalidateCalculatedLayout];
|
||||
[self setNeedsLayout];
|
||||
[self invalidateSize];
|
||||
}
|
||||
}
|
||||
|
||||
@ -487,7 +486,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
}
|
||||
|
||||
// Tell the display node superclasses that the cached layout is incorrect now
|
||||
[self invalidateCalculatedLayout];
|
||||
[self invalidateSize];
|
||||
|
||||
// Force display to create renderer with new size and redisplay with new string
|
||||
[self setNeedsDisplay];
|
||||
@ -510,7 +509,7 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ];
|
||||
|
||||
_exclusionPaths = [exclusionPaths copy];
|
||||
[self _invalidateRenderer];
|
||||
[self invalidateCalculatedLayout];
|
||||
[self invalidateSize];
|
||||
[self setNeedsDisplay];
|
||||
}
|
||||
|
||||
|
||||
@ -135,7 +135,7 @@
|
||||
ASDisplayNodeAssertMainThread();
|
||||
[super layoutSublayers];
|
||||
|
||||
[self.asyncdisplaykit_node __layout];
|
||||
[self.asyncdisplaykit_node __layoutSublayers];
|
||||
}
|
||||
|
||||
- (void)setNeedsDisplay
|
||||
|
||||
@ -52,7 +52,7 @@
|
||||
|
||||
// if super node is rasterizing descendants, subnodes will not have had layout calls because they don't have layers
|
||||
if (rasterizingFromAscendent) {
|
||||
[self __layout];
|
||||
[self __layoutSublayers];
|
||||
}
|
||||
|
||||
// Capture these outside the display block so they are retained.
|
||||
|
||||
@ -212,7 +212,7 @@ FOUNDATION_EXPORT NSString * const ASRenderingEngineDidDisplayNodesScheduledBefo
|
||||
*/
|
||||
- (void)__setNeedsDisplay;
|
||||
|
||||
- (void)__layout;
|
||||
- (void)__layoutSublayers;
|
||||
- (void)__setSupernode:(ASDisplayNode *)supernode;
|
||||
|
||||
/**
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
#import "DetailRootNode.h"
|
||||
#import "SampleSizingNode.h"
|
||||
|
||||
@interface DetailViewController () <ASDisplayNodeSizingDelegate>
|
||||
@interface DetailViewController ()// <ASDisplayNodeSizingDelegate>
|
||||
@property (strong, nonatomic) SampleSizingNode *sizingNode;
|
||||
|
||||
@property (strong, nonatomic) ASNetworkImageNode *imageNode;
|
||||
@ -40,7 +40,7 @@
|
||||
// Set the sizing delegate of the root node to the container
|
||||
_sizingNode = [SampleSizingNode new];
|
||||
_sizingNode.autoresizingMask = UIViewAutoresizingNone;
|
||||
_sizingNode.sizingDelegate = self;
|
||||
//_sizingNode.sizingDelegate = self;
|
||||
|
||||
_imageNode = [ASNetworkImageNode new];
|
||||
_imageNode.needsDisplayOnBoundsChange = YES;
|
||||
@ -53,7 +53,7 @@
|
||||
[_buttonNode setTitle:@"Some Title" withFont:nil withColor:nil forState:ASControlStateNormal];
|
||||
[_buttonNode setTitle:@"Some Bla" withFont:nil withColor:[UIColor orangeColor] forState:ASControlStateHighlighted];
|
||||
[_buttonNode addTarget:self action:@selector(buttonAction:) forControlEvents:ASControlNodeEventTouchUpInside];
|
||||
_buttonNode.sizingDelegate = self;
|
||||
//_buttonNode.sizingDelegate = self;
|
||||
|
||||
return self;
|
||||
}
|
||||
@ -74,7 +74,7 @@
|
||||
// Initial size of sizing node
|
||||
//self.sizingNode.frame = CGRectMake(100, 100, 50, 50);
|
||||
|
||||
[self displayNodeDidInvalidateSize:self.buttonNode];
|
||||
//[self displayNodeDidInvalidateSize:self.buttonNode];
|
||||
|
||||
// Initial size for image node
|
||||
// self.imageNode.frame = CGRectMake(50, 70, 100, 100);
|
||||
@ -94,6 +94,7 @@
|
||||
{
|
||||
[super viewDidLayoutSubviews];
|
||||
|
||||
// Updat the sizing for the button node
|
||||
[self updateButtonNodeLayout];
|
||||
|
||||
// Update the sizing node layout
|
||||
@ -116,23 +117,23 @@
|
||||
|
||||
// The sizing delegate will get callbacks if the size did invalidate of the display node. It's the job of the delegate
|
||||
// to get the new size from the display node and update the frame based on the returned size
|
||||
- (void)displayNodeDidInvalidateSize:(ASDisplayNode *)displayNode
|
||||
{
|
||||
if (displayNode == self.buttonNode) {
|
||||
[self updateButtonNodeLayout];
|
||||
return;
|
||||
}
|
||||
|
||||
[self updateNodeLayout];
|
||||
|
||||
/*dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
[self updateNodeLayoutRandom];
|
||||
});*/
|
||||
|
||||
/*[NSTimer scheduledTimerWithTimeInterval:2.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
|
||||
[self updateNodeLayoutRandom];
|
||||
}];*/
|
||||
}
|
||||
//- (void)displayNodeDidInvalidateSize:(ASDisplayNode *)displayNode
|
||||
//{
|
||||
// if (displayNode == self.buttonNode) {
|
||||
// [self updateButtonNodeLayout];
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// [self updateNodeLayout];
|
||||
//
|
||||
// /*dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
// [self updateNodeLayoutRandom];
|
||||
// });*/
|
||||
//
|
||||
// /*[NSTimer scheduledTimerWithTimeInterval:2.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
|
||||
// [self updateNodeLayoutRandom];
|
||||
// }];*/
|
||||
//}
|
||||
|
||||
- (void)updateNodeLayout
|
||||
{
|
||||
@ -140,29 +141,34 @@
|
||||
//return;
|
||||
// Use the bounds of the view and get the fitting size
|
||||
// This does not have any side effects, but can be called on the main thread without any problems
|
||||
CGSize size = [self.sizingNode sizeThatFits:CGSizeMake(CGFLOAT_MAX, 100.0)];
|
||||
CGSize size = [self.sizingNode sizeThatFits:CGSizeMake(INFINITY, 100.0)];
|
||||
//size.width -= 10;
|
||||
//[self.sizingNode setNeedsLayout];
|
||||
self.sizingNode.frame = CGRectMake((self.view.bounds.size.width - size.width) / 2.0,
|
||||
(self.view.bounds.size.height - size.height) / 2.0,
|
||||
size.width, size.height);
|
||||
self.sizingNode.frame = CGRectMake((CGRectGetWidth(self.view.bounds) - size.width) / 2.0,
|
||||
(CGRectGetHeight(self.view.bounds) - size.height) / 2.0,
|
||||
size.width,
|
||||
size.height);
|
||||
|
||||
//dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
// Decrease the frame a bit
|
||||
self.sizingNode.frame = CGRectInset(self.sizingNode.frame, 10, 10);
|
||||
//});
|
||||
}
|
||||
|
||||
- (void)updateNodeLayoutRandom
|
||||
{
|
||||
CGRect bounds = self.view.bounds;
|
||||
|
||||
// Pick a randome width and height and set the frame of the node
|
||||
CGSize size = CGSizeZero;
|
||||
size.width = arc4random_uniform(self.view.bounds.size.width);
|
||||
size.height = arc4random_uniform(self.view.bounds.size.height);
|
||||
size.width = arc4random_uniform(CGRectGetWidth(bounds));
|
||||
size.height = arc4random_uniform(CGRectGetHeight(bounds));
|
||||
|
||||
//[self.sizingNode setNeedsLayout];
|
||||
self.sizingNode.frame = CGRectMake((self.view.bounds.size.width - size.width) / 2.0,
|
||||
(self.view.bounds.size.height - size.height) / 2.0,
|
||||
size.width, size.height);
|
||||
self.sizingNode.frame = CGRectMake((CGRectGetWidth(bounds) - size.width) / 2.0,
|
||||
(CGRectGetHeight(bounds) - size.height) / 2.0,
|
||||
size.width,
|
||||
size.height);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -8,10 +8,27 @@
|
||||
|
||||
#import "SampleSizingNode.h"
|
||||
|
||||
@interface SampleSizingNodeSubnode : ASDisplayNode
|
||||
@property (strong, nonatomic) ASTextNode *textNode;
|
||||
@end
|
||||
|
||||
@implementation SampleSizingNodeSubnode
|
||||
|
||||
- (void)layout
|
||||
{
|
||||
[super layout];
|
||||
|
||||
// Manual layout after the normal layout engine did it's job
|
||||
// Calculated size can be used after the layout spec pass happened
|
||||
//self.textNode.frame = CGRectMake(self.textNode.frame.origin.x, self.textNode.frame.origin.y, self.textNode.calculatedSize.width, 20);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface SampleSizingNode ()
|
||||
@property (nonatomic, strong) ASDisplayNode *subnode;
|
||||
@property (nonatomic, assign) NSInteger state;
|
||||
|
||||
@property (nonatomic, strong) SampleSizingNodeSubnode *subnode;
|
||||
@property (nonatomic, strong) ASTextNode *textNode;
|
||||
@property (nonatomic, strong) ASNetworkImageNode *imageNode;
|
||||
@end
|
||||
@ -35,13 +52,15 @@
|
||||
_imageNode.backgroundColor = [UIColor brownColor];
|
||||
_imageNode.needsDisplayOnBoundsChange = YES;
|
||||
_imageNode.style.height = ASDimensionMakeWithFraction(1.0);
|
||||
_imageNode.style.width = ASDimensionMake(30.0);
|
||||
_imageNode.style.width = ASDimensionMake(50.0);
|
||||
|
||||
|
||||
_subnode = [ASDisplayNode new];
|
||||
_subnode = [SampleSizingNodeSubnode new];
|
||||
_subnode.textNode = _textNode;
|
||||
_subnode.backgroundColor = [UIColor redColor];
|
||||
_subnode.automaticallyManagesSubnodes = YES;
|
||||
|
||||
// Layout description via layoutSpecBlock
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
_subnode.layoutSpecBlock = ^ASLayoutSpec *(__kindof ASDisplayNode * _Nonnull node, ASSizeRange constrainedSize) {
|
||||
|
||||
@ -113,7 +132,6 @@
|
||||
[self invalidateSize];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - ASDisplayNode
|
||||
|
||||
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||
@ -129,5 +147,13 @@
|
||||
child:self.subnode];
|
||||
}
|
||||
|
||||
- (void)layout
|
||||
{
|
||||
[super layout];
|
||||
|
||||
// Layout after the official layout pass happened
|
||||
//self.subnode.frame = CGRectMake(self.subnode.frame.origin.x, self.subnode.frame.origin.y, 100, self.calculatedSize.height);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@ -201,7 +201,7 @@ static const CGFloat kInnerPadding = 10.0f;
|
||||
- (void)toggleImageEnlargement
|
||||
{
|
||||
_isImageEnlarged = !_isImageEnlarged;
|
||||
[self setNeedsLayout];
|
||||
[self invalidateSize];
|
||||
}
|
||||
|
||||
- (void)toggleNodesSwap
|
||||
@ -211,7 +211,7 @@ static const CGFloat kInnerPadding = 10.0f;
|
||||
[UIView animateWithDuration:0.15 animations:^{
|
||||
self.alpha = 0;
|
||||
} completion:^(BOOL finished) {
|
||||
[self setNeedsLayout];
|
||||
[self invalidateSize];
|
||||
[self.view layoutIfNeeded];
|
||||
|
||||
[UIView animateWithDuration:0.15 animations:^{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user