@@ -650,10 +650,15 @@ - (BOOL)shouldMeasureWithSizeRange:(ASSizeRange)constrainedSize
650650 }
651651 }
652652
653- // only calculate the size if
654- // - we haven't already
655- // - the constrained size range is different
656- return (!_flags.isMeasured || !ASSizeRangeEqualToSizeRange (constrainedSize, _layout.constrainedSizeRange ));
653+ // Only generate a new layout if:
654+ // - The current layout is dirty
655+ // - The passed constrained size is different than the layout's constrained size
656+ return ([self _dirtyLayout ] || !ASSizeRangeEqualToSizeRange (constrainedSize, _layout.constrainedSizeRange ));
657+ }
658+
659+ - (BOOL )_dirtyLayout
660+ {
661+ return _layout == nil || _layout.isDirty ;
657662}
658663
659664#pragma mark - Layout Transition
@@ -1019,7 +1024,7 @@ - (void)__setNeedsLayout
10191024 ASDisplayNodeAssertThreadAffinity (self);
10201025 ASDN::MutexLocker l (_propertyLock);
10211026
1022- if (!_flags. isMeasured ) {
1027+ if ([ self _dirtyLayout ] ) {
10231028 return ;
10241029 }
10251030
@@ -1095,7 +1100,7 @@ - (void)measureNodeWithBoundsIfNecessary:(CGRect)bounds
10951100 // Normally measure will be called before layout occurs. If this doesn't happen, nothing is going to call it at all.
10961101 // We simply call measureWithSizeRange: using a size range equal to whatever bounds were provided to that element or
10971102 // try to measure the node with the largest size as possible
1098- if (self.supernode == nil && !self.supportsRangeManagedInterfaceState && !_flags. isMeasured ) {
1103+ if (self.supernode == nil && !self.supportsRangeManagedInterfaceState && [ self _dirtyLayout ] == NO ) {
10991104 if (CGRectEqualToRect (bounds, CGRectZero)) {
11001105 LOG (@" Warning: No size given for node before node was trying to layout itself: %@ . Please provide a frame for the node." , self);
11011106 } else {
@@ -1108,7 +1113,7 @@ - (void)layout
11081113{
11091114 ASDisplayNodeAssertMainThread ();
11101115
1111- if (!_flags. isMeasured ) {
1116+ if ([ self _dirtyLayout ] ) {
11121117 return ;
11131118 }
11141119
@@ -2058,8 +2063,10 @@ - (UIImage *)placeholderImage
20582063- (void )invalidateCalculatedLayout
20592064{
20602065 ASDN::MutexLocker l (_propertyLock);
2061- // This will cause -measureWithSizeRange: to actually compute the size instead of returning the previously cached size
2062- _flags.isMeasured = NO ;
2066+
2067+ // This will cause the next call to -measureWithSizeRange: to actually compute a new layout
2068+ // instead of returning the current layout
2069+ _layout.dirty = YES ;
20632070}
20642071
20652072- (void )__didLoad
@@ -2395,17 +2402,14 @@ - (void)applyPendingLayoutContext
23952402 }
23962403}
23972404
2398- - (void )applyLayout : (ASLayout *)layout
2399- layoutContext : (ASLayoutTransition *)layoutContext
2405+ - (void )applyLayout : (ASLayout *)layout layoutContext : (ASLayoutTransition *)layoutContext
24002406{
24012407 ASDN::MutexLocker l (_propertyLock);
24022408 _layout = layout;
24032409
24042410 ASDisplayNodeAssertTrue (layout.layoutableObject == self);
24052411 ASDisplayNodeAssertTrue (layout.size .width >= 0.0 );
24062412 ASDisplayNodeAssertTrue (layout.size .height >= 0.0 );
2407-
2408- _flags.isMeasured = YES ;
24092413
24102414 if (self.usesImplicitHierarchyManagement && layoutContext != nil ) {
24112415 [layoutContext applySubnodeInsertions ];
0 commit comments