mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-17 03:40:18 +00:00
[Layout] Automatic measurement on layout fixes (#2206)
* Don't measure range managed nodes automatically in the layout pass * Fix auto measure a node mid transition
This commit is contained in:
parent
8897614f0e
commit
0aeefaf25f
@ -1382,17 +1382,28 @@ ASLayoutableSizeHelperForwarding
|
|||||||
|
|
||||||
- (void)measureNodeWithBoundsIfNecessary:(CGRect)bounds
|
- (void)measureNodeWithBoundsIfNecessary:(CGRect)bounds
|
||||||
{
|
{
|
||||||
|
BOOL supportsRangeManagedInterfaceState = NO;
|
||||||
BOOL hasDirtyLayout = NO;
|
BOOL hasDirtyLayout = NO;
|
||||||
CGSize calculatedLayoutSize = CGSizeZero;
|
CGSize calculatedLayoutSize = CGSizeZero;
|
||||||
{
|
{
|
||||||
ASDN::MutexLocker l(__instanceLock__);
|
ASDN::MutexLocker l(__instanceLock__);
|
||||||
|
supportsRangeManagedInterfaceState = [self supportsRangeManagedInterfaceState];
|
||||||
hasDirtyLayout = _calculatedDisplayNodeLayout->isDirty();
|
hasDirtyLayout = _calculatedDisplayNodeLayout->isDirty();
|
||||||
calculatedLayoutSize = _calculatedDisplayNodeLayout->layout.size;
|
calculatedLayoutSize = _calculatedDisplayNodeLayout->layout.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if it's a subnode in a layout transition. In this case no measurement is needed as it's part of
|
||||||
|
// the layout transition
|
||||||
|
if (ASHierarchyStateIncludesLayoutPending(_hierarchyState)) {
|
||||||
|
ASLayoutableContext context = ASLayoutableGetCurrentContext();
|
||||||
|
if (ASLayoutableContextIsNull(context) || _pendingTransitionID != context.transitionID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If no measure pass happened or the bounds changed between layout passes we manually trigger a measurement pass
|
// 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
|
// for the node using a size range equal to whatever bounds were provided to the node
|
||||||
if (hasDirtyLayout || CGSizeEqualToSize(calculatedLayoutSize, bounds.size) == NO) {
|
if (supportsRangeManagedInterfaceState == NO && (hasDirtyLayout || CGSizeEqualToSize(calculatedLayoutSize, bounds.size) == NO)) {
|
||||||
if (CGRectEqualToRect(bounds, CGRectZero)) {
|
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);
|
LOG(@"Warning: No size given for node before node was trying to layout itself: %@. Please provide a frame for the node.", self);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -44,31 +44,6 @@
|
|||||||
ASXCTAssertEqualSizes(buttonNode.calculatedSize, nodeSize, @"Automatic measurement pass should have happened in layout pass");
|
ASXCTAssertEqualSizes(buttonNode.calculatedSize, nodeSize, @"Automatic measurement pass should have happened in layout pass");
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)testMeasureOnLayoutIfNotHappenedBeforeForRangeManagedNodes
|
|
||||||
{
|
|
||||||
CGSize nodeSize = CGSizeMake(100, 100);
|
|
||||||
|
|
||||||
ASDisplayNode *displayNode = [ASDisplayNode new];
|
|
||||||
[displayNode setSizeWithCGSize:nodeSize];
|
|
||||||
|
|
||||||
ASButtonNode *buttonNode = [ASButtonNode new];
|
|
||||||
[displayNode addSubnode:buttonNode];
|
|
||||||
|
|
||||||
[displayNode enterHierarchyState:ASHierarchyStateRangeManaged];
|
|
||||||
|
|
||||||
displayNode.frame = {.size = nodeSize};
|
|
||||||
buttonNode.frame = {.size = nodeSize};
|
|
||||||
|
|
||||||
ASXCTAssertEqualSizes(displayNode.calculatedSize, CGSizeZero, @"Calculated size before measurement and layout should be 0");
|
|
||||||
ASXCTAssertEqualSizes(buttonNode.calculatedSize, CGSizeZero, @"Calculated size before measurement and layout should be 0");
|
|
||||||
|
|
||||||
// Trigger layout pass without a maeasurment pass before
|
|
||||||
[displayNode.view layoutIfNeeded];
|
|
||||||
|
|
||||||
ASXCTAssertEqualSizes(displayNode.calculatedSize, nodeSize, @"Automatic measurement pass should have happened in layout pass");
|
|
||||||
ASXCTAssertEqualSizes(buttonNode.calculatedSize, nodeSize, @"Automatic measurement pass should have happened in layout pass");
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
- (void)testNotAllowAddingSubnodesInLayoutSpecThatFits
|
- (void)testNotAllowAddingSubnodesInLayoutSpecThatFits
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1988,7 +1988,7 @@ static bool stringContainsPointer(NSString *description, id p) {
|
|||||||
|
|
||||||
// FIXME
|
// FIXME
|
||||||
// Supernode is measured, subnode isnt, transition starts, UIKit does a layout pass before measurement finishes
|
// Supernode is measured, subnode isnt, transition starts, UIKit does a layout pass before measurement finishes
|
||||||
- (void)DISABLED_testThatItsSafeToAutomeasureANodeMidTransition
|
- (void)testThatItsSafeToAutomeasureANodeMidTransition
|
||||||
{
|
{
|
||||||
ASDisplayNode *supernode = [[ASDisplayNode alloc] init];
|
ASDisplayNode *supernode = [[ASDisplayNode alloc] init];
|
||||||
[supernode layoutThatFits:ASSizeRangeMake(CGSizeZero, CGSizeMake(100, 100))];
|
[supernode layoutThatFits:ASSizeRangeMake(CGSizeZero, CGSizeMake(100, 100))];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user