Skip to content

Commit

Permalink
Invalidate layouts more aggressively when transitioning with animation (
Browse files Browse the repository at this point in the history
#476)

* Be more aggressive at invalidating layouts during transitions, add a debug method, fix some build errors when verbose logging

* Add a changelog entry
  • Loading branch information
Adlai-Holler authored Jul 27, 2017
1 parent 7b05458 commit 01c14f0
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Add ASCollectionGalleryLayoutDelegate - an async collection layout that makes same-size collections (e.g photo galleries, pagers, etc) fast and lightweight! [Huy Nguyen](https://github.com/nguyenhuy/) [#76](https://github.com/TextureGroup/Texture/pull/76) [#451](https://github.com/TextureGroup/Texture/pull/451)
- Fix an issue that causes infinite layout loop in ASDisplayNode after [#428](https://github.com/TextureGroup/Texture/pull/428) [Huy Nguyen](https://github.com/nguyenhuy) [#455](https://github.com/TextureGroup/Texture/pull/455)
- Fix an issue in layout transition that causes it to unexpectedly use the old layout [Huy Nguyen](https://github.com/nguyenhuy) [#464](https://github.com/TextureGroup/Texture/pull/464)
- Add -[ASDisplayNode detailedLayoutDescription] property to aid debugging. [Adlai Holler](https://github.com/Adlai-Holler) [#476](https://github.com/TextureGroup/Texture/pull/476)

##2.3.5
- Fix an issue where inserting/deleting sections could lead to inconsistent supplementary element behavior. [Adlai Holler](https://github.com/Adlai-Holler)
Expand Down
14 changes: 7 additions & 7 deletions Source/ASDisplayNode+Layout.mm
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ - (void)_locked_measureNodeWithBoundsIfNecessary:(CGRect)bounds
}

as_activity_create_for_scope("Update node layout for current bounds");
as_log_verbose(ASLayoutLog(), "Node %@, bounds size %@, calculatedSize %@, calculatedIsDirty %d", self, NSStringFromCGSize(boundsSizeForLayout), NSStringFromCGSize(_calculatedDisplayNodeLayout->layout.size), _calculatedDisplayNodeLayout->isDirty());
as_log_verbose(ASLayoutLog(), "Node %@, bounds size %@, calculatedSize %@, calculatedIsDirty %d", self, NSStringFromCGSize(boundsSizeForLayout), NSStringFromCGSize(_calculatedDisplayNodeLayout->layout.size), _calculatedDisplayNodeLayout->version < _layoutVersion.load());
// _calculatedDisplayNodeLayout is not reusable we need to transition to a new one
[self cancelLayoutTransition];

Expand Down Expand Up @@ -543,7 +543,6 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
return;
}

BOOL shouldInvalidateLayout = NO;
{
ASDN::MutexLocker l(__instanceLock__);

Expand All @@ -557,13 +556,14 @@ - (void)transitionLayoutWithSizeRange:(ASSizeRange)constrainedSize
ASDisplayNodeAssert(NO, @"Can't start a transition when one of the supernodes is performing one.");
return;
}

shouldInvalidateLayout = ASSizeRangeEqualToSizeRange([self _locked_constrainedSizeForCalculatedLayout], constrainedSize);
}

if (shouldInvalidateLayout) {
[self setNeedsLayout];
}
// Invalidate calculated layout because this method acts as an animated "setNeedsLayout" for nodes.
// If the user has reconfigured the node and calls this, we should never return a stale layout
// for subsequent calls to layoutThatFits: regardless of size range. We choose this method rather than
// -setNeedsLayout because that method also triggers a CA layout invalidation, which isn't necessary at this time.
// See https://github.com/TextureGroup/Texture/issues/463
[self invalidateCalculatedLayout];

// Every new layout transition has a transition id associated to check in subsequent transitions for cancelling
int32_t transitionID = [self _startNewTransition];
Expand Down
5 changes: 5 additions & 0 deletions Source/ASDisplayNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,11 @@ extern NSInteger const ASDefaultDrawingPriority;
*/
- (NSString *)displayNodeRecursiveDescription AS_WARN_UNUSED_RESULT;

/**
* A detailed description of this node's layout state. This is useful when debugging.
*/
@property (atomic, copy, readonly) NSString *detailedLayoutDescription;

@end

/**
Expand Down
32 changes: 32 additions & 0 deletions Source/ASDisplayNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3377,6 +3377,38 @@ - (NSString *)_recursiveDescriptionHelperWithIndent:(NSString *)indent
return subtree;
}

- (NSString *)detailedLayoutDescription
{
ASPushMainThreadAssertionsDisabled();
ASDN::MutexLocker l(__instanceLock__);
auto props = [NSMutableArray<NSDictionary *> array];

[props addObject:@{ @"layoutVersion": @(_layoutVersion.load()) }];
[props addObject:@{ @"bounds": [NSValue valueWithCGRect:self.bounds] }];

if (_calculatedDisplayNodeLayout != nullptr) {
ASDisplayNodeLayout c = *_calculatedDisplayNodeLayout;
[props addObject:@{ @"calculatedLayout": c.layout }];
[props addObject:@{ @"calculatedVersion": @(c.version) }];
[props addObject:@{ @"calculatedConstrainedSize" : NSStringFromASSizeRange(c.constrainedSize) }];
if (c.requestedLayoutFromAbove) {
[props addObject:@{ @"calculatedRequestedLayoutFromAbove": @"YES" }];
}
}
if (_pendingDisplayNodeLayout != nullptr) {
ASDisplayNodeLayout p = *_pendingDisplayNodeLayout;
[props addObject:@{ @"pendingLayout": p.layout }];
[props addObject:@{ @"pendingVersion": @(p.version) }];
[props addObject:@{ @"pendingConstrainedSize" : NSStringFromASSizeRange(p.constrainedSize) }];
if (p.requestedLayoutFromAbove) {
[props addObject:@{ @"pendingRequestedLayoutFromAbove": (id)kCFNull }];
}
}

ASPopMainThreadAssertionsDisabled();
return ASObjectDescriptionMake(self, props);
}

@end

#pragma mark - ASDisplayNode UIKit / CA Categories
Expand Down
2 changes: 1 addition & 1 deletion Source/ASNetworkImageNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ - (void)_lazilyLoadImageIfNecessary
return;
}

as_log_verbose(ASImageLoadingLog(), "Downloaded image for %@ img: %@ url: %@", self, [imageContainer asdk_image], url);
as_log_verbose(ASImageLoadingLog(), "Downloaded image for %@ img: %@ url: %@", self, [imageContainer asdk_image], URL);

// Grab the lock for the rest of the block
ASDN::MutexLocker l(strongSelf->__instanceLock__);
Expand Down

0 comments on commit 01c14f0

Please sign in to comment.