diff --git a/Source/ASDisplayNode+Beta.h b/Source/ASDisplayNode+Beta.h index e5f1ee225..61616066b 100644 --- a/Source/ASDisplayNode+Beta.h +++ b/Source/ASDisplayNode+Beta.h @@ -167,8 +167,8 @@ extern void ASDisplayNodePerformBlockOnEveryYogaChild(ASDisplayNode * _Nullable @interface ASDisplayNode (Yoga) -@property (nonatomic, strong) NSArray *yogaChildren; -@property (nonatomic, strong) ASLayout *yogaCalculatedLayout; +@property (nonatomic, strong, nullable) NSArray *yogaChildren; +@property (nonatomic, strong, nullable) ASLayout *yogaCalculatedLayout; - (void)addYogaChild:(ASDisplayNode *)child; - (void)removeYogaChild:(ASDisplayNode *)child; diff --git a/Source/ASDisplayNode+Yoga.mm b/Source/ASDisplayNode+Yoga.mm index 43166d5c5..4454e3561 100644 --- a/Source/ASDisplayNode+Yoga.mm +++ b/Source/ASDisplayNode+Yoga.mm @@ -335,6 +335,7 @@ - (void)invalidateCalculatedYogaLayout if (YGNodeGetMeasureFunc(yogaNode)) { YGNodeMarkDirty(yogaNode); } + self.yogaCalculatedLayout = nil; } - (void)semanticContentAttributeDidChange:(UISemanticContentAttribute)attribute @@ -350,7 +351,7 @@ - (void)semanticContentAttributeDidChange:(UISemanticContentAttribute)attribute - (void)calculateLayoutFromYogaRoot:(ASSizeRange)rootConstrainedSize { if (self.yogaParent) { - if (ASHierarchyStateIncludesYogaLayoutMeasuring(self.hierarchyState) == NO) { + if (self.yogaCalculatedLayout == nil) { [self _setNeedsLayoutFromAbove]; } return; diff --git a/Source/ASDisplayNode.mm b/Source/ASDisplayNode.mm index 303775a5f..ef5fa5ffe 100644 --- a/Source/ASDisplayNode.mm +++ b/Source/ASDisplayNode.mm @@ -1166,17 +1166,19 @@ - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize ASDN::MutexLocker l(__instanceLock__); #if YOGA /* YOGA */ - if (ASHierarchyStateIncludesYogaLayoutEnabled(_hierarchyState) == YES && - ASHierarchyStateIncludesYogaLayoutMeasuring(_hierarchyState) == NO) { - ASDN::MutexUnlocker ul(__instanceLock__); - [self calculateLayoutFromYogaRoot:constrainedSize]; - } + if (ASHierarchyStateIncludesYogaLayoutEnabled(_hierarchyState) == YES) { + if (ASHierarchyStateIncludesYogaLayoutMeasuring(_hierarchyState) == NO && self.yogaCalculatedLayout == nil) { + ASDN::MutexUnlocker ul(__instanceLock__); + [self calculateLayoutFromYogaRoot:constrainedSize]; + } - if (ASHierarchyStateIncludesYogaLayoutEnabled(_hierarchyState) == YES && self.yogaCalculatedLayout) { - return self.yogaCalculatedLayout; + // The call above may set yogaCalculatedLayout, even if it tested as nil to enter it. + if (self.yogaCalculatedLayout && self.yogaChildren.count > 0) { + return self.yogaCalculatedLayout; + } } #endif /* YOGA */ - + // Manual size calculation via calculateSizeThatFits: if (((_methodOverrides & ASDisplayNodeMethodOverrideLayoutSpecThatFits) || (_layoutSpecBlock != NULL)) == NO) {