[Layout] Automatic measure pass in layout pass if not happened before (#2163)

* Automatic measure pass in layout pass if not happened before

If no measure pass happened or the bounds changed between layout passes we manually trigger a measurement pass for the node using a size range equal to whatever bounds were provided to the node

* Add test method that ensures that on a second layout pass with same bounds, layoutSpecThatFits: / layoutSpecBlock is not called
This commit is contained in:
Michael Schneider
2016-08-31 16:45:02 -07:00
committed by Adlai Holler
parent ea4d88e053
commit 027358fc6b
2 changed files with 71 additions and 12 deletions

View File

@@ -1321,22 +1321,21 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
- (void)measureNodeWithBoundsIfNecessary:(CGRect)bounds
{
BOOL supportsRangedManagedInterfaceState = NO;
BOOL hasDirtyLayout = NO;
BOOL hasSupernode = NO;
CGSize calculatedLayoutSize = CGSizeZero;
{
ASDN::MutexLocker l(__instanceLock__);
supportsRangedManagedInterfaceState = [self supportsRangeManagedInterfaceState];
hasDirtyLayout = [self _hasDirtyLayout];
hasSupernode = (self.supernode != nil);
calculatedLayoutSize = _calculatedLayout.size;
}
// Normally measure will be called before layout occurs. If this doesn't happen, nothing is going to call it at all.
// We simply call measureWithSizeRange: using a size range equal to whatever bounds were provided to that element
if (!hasSupernode && !supportsRangedManagedInterfaceState && hasDirtyLayout) {
// If no measure pass happened or the bounds changed between layout passes we manually trigger a measurement pass
// for the node using a size range equal to whatever bounds were provided to the node
if (hasDirtyLayout || CGSizeEqualToSize(calculatedLayoutSize, bounds.size) == NO) {
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 {
// This is a no op if the bounds size is the same as the cosntrained size we used to create the layout previously
[self measureWithSizeRange:ASSizeRangeMake(bounds.size, bounds.size)];
}
}