Add detection for a loop if invalidation of a size is happening multiple times

This commit is contained in:
Michael Schneider
2016-11-17 18:21:27 -08:00
parent 5d61b2b4e6
commit b762998336
2 changed files with 12 additions and 3 deletions

View File

@@ -1539,7 +1539,15 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
// If the size of the new layout to apply did change from the current bounds, invalidate the whole tree up
// so the root node can handle a resizing if necessary
if (CGSizeEqualToSize(ASCeilSizeValues(bounds.size), pendingLayout->layout.size) == NO) {
if (pendingLayout->requestedLayoutFromAbove == NO &&
CGSizeEqualToSize(ASCeilSizeValues(bounds.size), pendingLayout->layout.size) == NO) {
// The layout that we have specifies that this node (self) would like to be a different size
// than it currently is. Because that size has been computed within the constrainedSize, we
// expect that doing setNeedsLayoutFromAbove will result in our parent resizing us to this.
// However, in some cases apps may manually interfere with this (setting a different bounds).
// In this case, we need to detect that we've already asked to be resized to match this
// particular ASLayout object, and shouldn't loop asking again unless we have a different ASLayout.
pendingLayout->requestedLayoutFromAbove = YES;
[self setNeedsLayoutFromAbove];
}

View File

@@ -24,6 +24,7 @@ struct ASDisplayNodeLayout {
ASLayout *layout;
ASSizeRange constrainedSize;
CGSize parentSize;
BOOL requestedLayoutFromAbove;
BOOL _dirty;
/*
@@ -33,13 +34,13 @@ struct ASDisplayNodeLayout {
* @param parentSize Parent size used to create the layout
*/
ASDisplayNodeLayout(ASLayout *layout, ASSizeRange constrainedSize, CGSize parentSize)
: layout(layout), constrainedSize(constrainedSize), parentSize(parentSize), _dirty(NO) {};
: layout(layout), constrainedSize(constrainedSize), parentSize(parentSize), requestedLayoutFromAbove(NO), _dirty(NO) {};
/*
* Creates a layout without any layout associated. By default this display node layout is dirty.
*/
ASDisplayNodeLayout()
: layout(nil), constrainedSize({{0, 0}, {0, 0}}), parentSize({0, 0}), _dirty(YES) {};
: layout(nil), constrainedSize({{0, 0}, {0, 0}}), parentSize({0, 0}), requestedLayoutFromAbove(NO), _dirty(YES) {};
/**
* Returns if the display node layout is dirty as it was invalidated or it was created without a layout.