mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-08 15:23:12 +00:00
Merge pull request #1735 from levi/betterFlatten3
[ASLayout] Clean up flattening process of ASLayout
This commit is contained in:
commit
c211c76c64
@ -62,7 +62,9 @@ NSString * const ASRenderingEngineDidDisplayNodesScheduledBeforeTimestamp = @"AS
|
||||
@implementation ASDisplayNode
|
||||
|
||||
// these dynamic properties all defined in ASLayoutOptionsPrivate.m
|
||||
@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis, alignSelf, ascender, descender, sizeRange, layoutPosition;
|
||||
@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis,
|
||||
alignSelf, ascender, descender, sizeRange, layoutPosition, layoutableType;
|
||||
|
||||
@synthesize name = _name;
|
||||
@synthesize preferredFrameSize = _preferredFrameSize;
|
||||
@synthesize isFinalLayoutable = _isFinalLayoutable;
|
||||
@ -659,6 +661,11 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
return _layout == nil || _layout.isDirty;
|
||||
}
|
||||
|
||||
- (ASLayoutableType)layoutableType
|
||||
{
|
||||
return ASLayoutableTypeDisplayNode;
|
||||
}
|
||||
|
||||
#pragma mark - Layout Transition
|
||||
|
||||
- (void)transitionLayoutWithAnimation:(BOOL)animated
|
||||
@ -1916,13 +1923,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
||||
ASLayoutableValidateLayout(layout);
|
||||
#endif
|
||||
}
|
||||
return [layout flattenedLayoutUsingPredicateBlock:^BOOL(ASLayout *evaluatedLayout) {
|
||||
if (self.usesImplicitHierarchyManagement) {
|
||||
return ASObjectIsEqual(layout, evaluatedLayout) == NO && [evaluatedLayout.layoutableObject isKindOfClass:[ASDisplayNode class]];
|
||||
} else {
|
||||
return [_subnodes containsObject:evaluatedLayout.layoutableObject];
|
||||
}
|
||||
}];
|
||||
return [layout filteredNodeLayoutTree];
|
||||
} else {
|
||||
// If neither -layoutSpecThatFits: nor -calculateSizeThatFits: is overridden by subclassses, preferredFrameSize should be used,
|
||||
// assume that the default implementation of -calculateSizeThatFits: returns it.
|
||||
@ -2415,7 +2416,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
|
||||
|
||||
- (void)__layoutSublayouts
|
||||
{
|
||||
for (ASLayout *subnodeLayout in _layout.immediateSublayouts) {
|
||||
for (ASLayout *subnodeLayout in _layout.sublayouts) {
|
||||
((ASDisplayNode *)subnodeLayout.layoutableObject).frame = [subnodeLayout frame];
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,6 +31,11 @@ extern BOOL CGPointIsNull(CGPoint point);
|
||||
*/
|
||||
@property (nonatomic, weak, readonly) id<ASLayoutable> layoutableObject;
|
||||
|
||||
/**
|
||||
* The type of ASLayoutable that created this layout
|
||||
*/
|
||||
@property (nonatomic, readonly) ASLayoutableType type;
|
||||
|
||||
/**
|
||||
* Size of the current layout
|
||||
*/
|
||||
@ -53,38 +58,39 @@ extern BOOL CGPointIsNull(CGPoint point);
|
||||
*/
|
||||
@property (nonatomic, readonly) NSArray<ASLayout *> *sublayouts;
|
||||
|
||||
/**
|
||||
* A list of sublayouts that were not already flattened.
|
||||
*/
|
||||
@property (nonatomic, readonly) NSArray<ASLayout *> *immediateSublayouts;
|
||||
|
||||
/**
|
||||
* Mark the layout dirty for future regeneration.
|
||||
*/
|
||||
@property (nonatomic, getter=isDirty) BOOL dirty;
|
||||
|
||||
/**
|
||||
* A boolean describing if the current layout has been flattened.
|
||||
* @abstract Returns a valid frame for the current layout computed with the size and position.
|
||||
* @discussion Clamps the layout's origin or position to 0 if any of the calculated values are infinite.
|
||||
*/
|
||||
@property (nonatomic, readonly, getter=isFlattened) BOOL flattened;
|
||||
@property (nonatomic, readonly) CGRect frame;
|
||||
|
||||
/**
|
||||
* Initializer.
|
||||
* Designated initializer
|
||||
*/
|
||||
- (instancetype)initWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||
size:(CGSize)size
|
||||
position:(CGPoint)position
|
||||
sublayouts:(NSArray *)sublayouts NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Convenience class initializer for layout construction.
|
||||
*
|
||||
* @param layoutableObject The backing ASLayoutable object.
|
||||
*
|
||||
* @param size The size of this layout.
|
||||
*
|
||||
* @param position The position of this layout within its parent (if available).
|
||||
*
|
||||
* @param sublayouts Sublayouts belong to the new layout.
|
||||
* @param size The size of this layout.
|
||||
* @param position The position of this layout within its parent (if available).
|
||||
* @param sublayouts Sublayouts belong to the new layout.
|
||||
*/
|
||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||
size:(CGSize)size
|
||||
position:(CGPoint)position
|
||||
sublayouts:(nullable NSArray<ASLayout *> *)sublayouts
|
||||
flattened:(BOOL)flattened;
|
||||
sublayouts:(nullable NSArray<ASLayout *> *)sublayouts;
|
||||
|
||||
/**
|
||||
* Convenience initializer that has CGPointNull position.
|
||||
@ -93,9 +99,7 @@ extern BOOL CGPointIsNull(CGPoint point);
|
||||
* or for creating a sublayout of which the position is yet to be determined.
|
||||
*
|
||||
* @param layoutableObject The backing ASLayoutable object.
|
||||
*
|
||||
* @param size The size of this layout.
|
||||
*
|
||||
* @param sublayouts Sublayouts belong to the new layout.
|
||||
*/
|
||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||
@ -109,7 +113,6 @@ extern BOOL CGPointIsNull(CGPoint point);
|
||||
* or a sublayout of which the position is yet to be determined.
|
||||
*
|
||||
* @param layoutableObject The backing ASLayoutable object.
|
||||
*
|
||||
* @param size The size of this layout.
|
||||
*/
|
||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||
@ -120,9 +123,7 @@ extern BOOL CGPointIsNull(CGPoint point);
|
||||
* Convenience initializer that is flattened and has CGPointNull position.
|
||||
*
|
||||
* @param layoutableObject The backing ASLayoutable object.
|
||||
*
|
||||
* @param size The size of this layout.
|
||||
*
|
||||
* @param sublayouts Sublayouts belong to the new layout.
|
||||
*/
|
||||
+ (instancetype)flattenedLayoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||
@ -131,22 +132,16 @@ extern BOOL CGPointIsNull(CGPoint point);
|
||||
sublayouts:(nullable NSArray<ASLayout *> *)sublayouts;
|
||||
|
||||
/**
|
||||
* @abstract Evaluates a given predicate block against each object in the receiving layout tree
|
||||
* and returns a new, 1-level deep layout containing the objects for which the predicate block returns true.
|
||||
*
|
||||
* @param predicateBlock The block is applied to a layout to be evaluated.
|
||||
* The block takes 1 argument: evaluatedLayout - the layout to be evaluated.
|
||||
* The block returns YES if evaluatedLayout evaluates to true, otherwise NO.
|
||||
*
|
||||
* @return A new, 1-level deep layout containing the layouts for which the predicate block returns true.
|
||||
* Convenience initializer that creates a layout based on the values of the given layout, with a new position
|
||||
* @param layout The layout to use to create the new layout
|
||||
* @param position The position of the new layout
|
||||
*/
|
||||
- (ASLayout *)flattenedLayoutUsingPredicateBlock:(BOOL (^)(ASLayout *evaluatedLayout))predicateBlock;
|
||||
+ (instancetype)layoutWithLayout:(ASLayout *)layout position:(CGPoint)position;
|
||||
|
||||
/**
|
||||
* @abstract Returns a valid frame for the current layout computed with the size and position.
|
||||
* @discussion Clamps the layout's origin or position to 0 if any of the calculated values are infinite.
|
||||
* Traverses the existing layout tree and generates a new tree that represents only ASDisplayNode layouts
|
||||
*/
|
||||
- (CGRect)frame;
|
||||
- (ASLayout *)filteredNodeLayoutTree;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@ -9,10 +9,12 @@
|
||||
*/
|
||||
|
||||
#import "ASLayout.h"
|
||||
|
||||
#import "ASAssert.h"
|
||||
#import "ASLayoutSpecUtilities.h"
|
||||
#import "ASInternalHelpers.h"
|
||||
#import "ASDimension.h"
|
||||
#import "ASInternalHelpers.h"
|
||||
#import "ASLayoutSpecUtilities.h"
|
||||
|
||||
#import <queue>
|
||||
|
||||
CGPoint const CGPointNull = {NAN, NAN};
|
||||
@ -22,25 +24,35 @@ extern BOOL CGPointIsNull(CGPoint point)
|
||||
return isnan(point.x) && isnan(point.y);
|
||||
}
|
||||
|
||||
@interface ASLayout ()
|
||||
|
||||
/**
|
||||
* A boolean describing if the current layout has been flattened.
|
||||
*/
|
||||
@property (nonatomic, getter=isFlattened) BOOL flattened;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ASLayout
|
||||
|
||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||
size:(CGSize)size
|
||||
position:(CGPoint)position
|
||||
sublayouts:(NSArray *)sublayouts
|
||||
flattened:(BOOL)flattened
|
||||
@dynamic frame, type;
|
||||
|
||||
- (instancetype)initWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||
size:(CGSize)size
|
||||
position:(CGPoint)position
|
||||
sublayouts:(NSArray *)sublayouts
|
||||
{
|
||||
ASDisplayNodeAssert(layoutableObject, @"layoutableObject is required.");
|
||||
self = [super init];
|
||||
if (self) {
|
||||
NSParameterAssert(layoutableObject);
|
||||
#if DEBUG
|
||||
for (ASLayout *sublayout in sublayouts) {
|
||||
ASDisplayNodeAssert(!CGPointIsNull(sublayout.position), @"Invalid position is not allowed in sublayout.");
|
||||
}
|
||||
for (ASLayout *sublayout in sublayouts) {
|
||||
ASDisplayNodeAssert(CGPointIsNull(sublayout.position) == NO, @"Invalid position is not allowed in sublayout.");
|
||||
}
|
||||
#endif
|
||||
|
||||
ASLayout *l = [super new];
|
||||
if (l) {
|
||||
l->_layoutableObject = layoutableObject;
|
||||
|
||||
_layoutableObject = layoutableObject;
|
||||
|
||||
if (!isValidForLayout(size.width) || !isValidForLayout(size.height)) {
|
||||
ASDisplayNodeAssert(NO, @"layoutSize is invalid and unsafe to provide to Core Animation! Production will force to 0, 0. Size = %@, node = %@", NSStringFromCGSize(size), layoutableObject);
|
||||
@ -48,27 +60,40 @@ extern BOOL CGPointIsNull(CGPoint point)
|
||||
} else {
|
||||
size = CGSizeMake(ASCeilPixelValue(size.width), ASCeilPixelValue(size.height));
|
||||
}
|
||||
l->_constrainedSizeRange = sizeRange;
|
||||
l->_size = size;
|
||||
l->_dirty = NO;
|
||||
_constrainedSizeRange = sizeRange;
|
||||
_size = size;
|
||||
_dirty = NO;
|
||||
|
||||
if (CGPointIsNull(position) == NO) {
|
||||
l->_position = CGPointMake(ASCeilPixelValue(position.x), ASCeilPixelValue(position.y));
|
||||
_position = CGPointMake(ASCeilPixelValue(position.x), ASCeilPixelValue(position.y));
|
||||
} else {
|
||||
l->_position = position;
|
||||
_position = position;
|
||||
}
|
||||
l->_sublayouts = [sublayouts copy];
|
||||
l->_flattened = flattened;
|
||||
|
||||
NSMutableArray<ASLayout *> *result = [NSMutableArray array];
|
||||
for (ASLayout *sublayout in l->_sublayouts) {
|
||||
if (!sublayout.isFlattened) {
|
||||
[result addObject:sublayout];
|
||||
}
|
||||
}
|
||||
l->_immediateSublayouts = result;
|
||||
_sublayouts = sublayouts != nil ? [sublayouts copy] : @[];
|
||||
_flattened = NO;
|
||||
}
|
||||
return l;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
ASDisplayNodeAssert(NO, @"Use the designated initializer");
|
||||
return [self init];
|
||||
}
|
||||
|
||||
#pragma mark - Class Constructors
|
||||
|
||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||
constrainedSizeRange:(ASSizeRange)sizeRange
|
||||
size:(CGSize)size
|
||||
position:(CGPoint)position
|
||||
sublayouts:(NSArray *)sublayouts
|
||||
{
|
||||
return [[self alloc] initWithLayoutableObject:layoutableObject
|
||||
constrainedSizeRange:sizeRange
|
||||
size:size
|
||||
position:position
|
||||
sublayouts:sublayouts];
|
||||
}
|
||||
|
||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||
@ -80,8 +105,7 @@ extern BOOL CGPointIsNull(CGPoint point)
|
||||
constrainedSizeRange:sizeRange
|
||||
size:size
|
||||
position:CGPointNull
|
||||
sublayouts:sublayouts
|
||||
flattened:NO];
|
||||
sublayouts:sublayouts];
|
||||
}
|
||||
|
||||
+ (instancetype)layoutWithLayoutableObject:(id<ASLayoutable>)layoutableObject
|
||||
@ -103,53 +127,61 @@ extern BOOL CGPointIsNull(CGPoint point)
|
||||
constrainedSizeRange:sizeRange
|
||||
size:size
|
||||
position:CGPointNull
|
||||
sublayouts:sublayouts
|
||||
flattened:YES];
|
||||
sublayouts:sublayouts];
|
||||
}
|
||||
|
||||
- (ASLayout *)flattenedLayoutUsingPredicateBlock:(BOOL (^)(ASLayout *))predicateBlock
|
||||
+ (instancetype)layoutWithLayout:(ASLayout *)layout position:(CGPoint)position
|
||||
{
|
||||
return [self layoutWithLayoutableObject:layout.layoutableObject
|
||||
constrainedSizeRange:layout.constrainedSizeRange
|
||||
size:layout.size
|
||||
position:position
|
||||
sublayouts:layout.sublayouts];
|
||||
}
|
||||
|
||||
#pragma mark - Layout Flattening
|
||||
|
||||
- (ASLayout *)filteredNodeLayoutTree
|
||||
{
|
||||
NSMutableArray *flattenedSublayouts = [NSMutableArray array];
|
||||
|
||||
struct Context {
|
||||
ASLayout *layout;
|
||||
CGPoint absolutePosition;
|
||||
BOOL visited;
|
||||
BOOL flattened;
|
||||
};
|
||||
|
||||
// Queue used to keep track of sublayouts while traversing this layout in a BFS fashion.
|
||||
std::queue<Context> queue;
|
||||
queue.push({self, CGPointMake(0, 0), NO, NO});
|
||||
queue.push({self, CGPointMake(0, 0)});
|
||||
|
||||
while (!queue.empty()) {
|
||||
Context &context = queue.front();
|
||||
if (context.visited) {
|
||||
queue.pop();
|
||||
} else {
|
||||
context.visited = YES;
|
||||
|
||||
if (predicateBlock(context.layout)) {
|
||||
[flattenedSublayouts addObject:[ASLayout layoutWithLayoutableObject:context.layout.layoutableObject
|
||||
constrainedSizeRange:context.layout.constrainedSizeRange
|
||||
size:context.layout.size
|
||||
position:context.absolutePosition
|
||||
sublayouts:nil
|
||||
flattened:context.flattened]];
|
||||
}
|
||||
|
||||
for (ASLayout *sublayout in context.layout.sublayouts) {
|
||||
// Mark layout trees that have already been flattened for future identification of immediate sublayouts
|
||||
BOOL flattened = context.flattened ? : context.layout.flattened;
|
||||
queue.push({sublayout, context.absolutePosition + sublayout.position, NO, flattened});
|
||||
Context context = queue.front();
|
||||
queue.pop();
|
||||
|
||||
if (self != context.layout && context.layout.type == ASLayoutableTypeDisplayNode) {
|
||||
ASLayout *layout = [ASLayout layoutWithLayout:context.layout position:context.absolutePosition];
|
||||
layout.flattened = YES;
|
||||
[flattenedSublayouts addObject:layout];
|
||||
}
|
||||
|
||||
for (ASLayout *sublayout in context.layout.sublayouts) {
|
||||
if (sublayout.isFlattened == NO) {
|
||||
queue.push({sublayout, context.absolutePosition + sublayout.position});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [ASLayout flattenedLayoutWithLayoutableObject:_layoutableObject
|
||||
constrainedSizeRange:_constrainedSizeRange
|
||||
size:_size
|
||||
sublayouts:flattenedSublayouts];
|
||||
return [ASLayout layoutWithLayoutableObject:_layoutableObject
|
||||
constrainedSizeRange:_constrainedSizeRange
|
||||
size:_size
|
||||
sublayouts:flattenedSublayouts];
|
||||
}
|
||||
|
||||
#pragma mark - Accessors
|
||||
|
||||
- (ASLayoutableType)type
|
||||
{
|
||||
return _layoutableObject.layoutableType;
|
||||
}
|
||||
|
||||
- (CGRect)frame
|
||||
|
||||
@ -34,7 +34,8 @@
|
||||
@implementation ASLayoutSpec
|
||||
|
||||
// these dynamic properties all defined in ASLayoutOptionsPrivate.m
|
||||
@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis, alignSelf, ascender, descender, sizeRange, layoutPosition;
|
||||
@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis,
|
||||
alignSelf, ascender, descender, sizeRange, layoutPosition, layoutableType;
|
||||
@synthesize isFinalLayoutable = _isFinalLayoutable;
|
||||
|
||||
- (instancetype)init
|
||||
@ -48,6 +49,11 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (ASLayoutableType)layoutableType
|
||||
{
|
||||
return ASLayoutableTypeLayoutSpec;
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
|
||||
|
||||
@ -21,6 +21,11 @@
|
||||
@class ASLayout;
|
||||
@class ASLayoutSpec;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, ASLayoutableType) {
|
||||
ASLayoutableTypeLayoutSpec,
|
||||
ASLayoutableTypeDisplayNode
|
||||
};
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
@ -41,6 +46,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
@protocol ASLayoutable <ASEnvironment, ASStackLayoutable, ASStaticLayoutable, ASLayoutablePrivate, ASLayoutableExtensibility>
|
||||
|
||||
@property (nonatomic, readonly) ASLayoutableType layoutableType;
|
||||
|
||||
/**
|
||||
* @abstract Calculate a layout based on given size range.
|
||||
*
|
||||
@ -50,7 +57,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
*/
|
||||
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize;
|
||||
|
||||
|
||||
#pragma mark - Layout options from the Layoutable Protocols
|
||||
|
||||
#pragma mark - ASStackLayoutable
|
||||
|
||||
@ -67,7 +67,7 @@
|
||||
}
|
||||
if (_previousLayout) {
|
||||
NSIndexSet *insertions, *deletions;
|
||||
[_previousLayout.immediateSublayouts asdk_diffWithArray:_pendingLayout.immediateSublayouts
|
||||
[_previousLayout.sublayouts asdk_diffWithArray:_pendingLayout.sublayouts
|
||||
insertions:&insertions
|
||||
deletions:&deletions
|
||||
compareBlock:^BOOL(ASLayout *lhs, ASLayout *rhs) {
|
||||
@ -80,7 +80,7 @@
|
||||
&_removedSubnodes,
|
||||
&_removedSubnodePositions);
|
||||
} else {
|
||||
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [_pendingLayout.immediateSublayouts count])];
|
||||
NSIndexSet *indexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [_pendingLayout.sublayouts count])];
|
||||
findNodesInLayoutAtIndexes(_pendingLayout, indexes, &_insertedSubnodes, &_insertedSubnodePositions);
|
||||
_removedSubnodes = nil;
|
||||
}
|
||||
@ -160,7 +160,7 @@ static inline void findNodesInLayoutAtIndexesWithFilteredNodes(ASLayout *layout,
|
||||
std::vector<NSUInteger> positions = std::vector<NSUInteger>();
|
||||
NSUInteger idx = [indexes firstIndex];
|
||||
while (idx != NSNotFound) {
|
||||
ASDisplayNode *node = (ASDisplayNode *)layout.immediateSublayouts[idx].layoutableObject;
|
||||
ASDisplayNode *node = (ASDisplayNode *)layout.sublayouts[idx].layoutableObject;
|
||||
ASDisplayNodeCAssert(node, @"A flattened layout must consist exclusively of node sublayouts");
|
||||
// Ignore the odd case in which a non-node sublayout is accessed and the type cast fails
|
||||
if (node != nil) {
|
||||
|
||||
@ -71,7 +71,7 @@ NSString * const ASTransitionContextToLayoutKey = @"org.asyncdisplaykit.ASTransi
|
||||
- (NSArray<ASDisplayNode *> *)subnodesForKey:(NSString *)key
|
||||
{
|
||||
NSMutableArray<ASDisplayNode *> *subnodes = [NSMutableArray array];
|
||||
for (ASLayout *sublayout in [self layoutForKey:key].immediateSublayouts) {
|
||||
for (ASLayout *sublayout in [self layoutForKey:key].sublayouts) {
|
||||
[subnodes addObject:(ASDisplayNode *)sublayout.layoutableObject];
|
||||
}
|
||||
return subnodes;
|
||||
|
||||
@ -65,9 +65,7 @@
|
||||
constrainedSizeRange:sizeRange
|
||||
size:layout.size
|
||||
sublayouts:@[layout]];
|
||||
_layoutUnderTest = [layout flattenedLayoutUsingPredicateBlock:^BOOL(ASLayout *evaluatedLayout) {
|
||||
return [self.subnodes containsObject:(ASDisplayNode *)evaluatedLayout.layoutableObject];
|
||||
}];
|
||||
_layoutUnderTest = [layout filteredNodeLayoutTree];
|
||||
self.frame = CGRectMake(0, 0, _layoutUnderTest.size.width, _layoutUnderTest.size.height);
|
||||
[self measure:_layoutUnderTest.size];
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user