diff --git a/AsyncDisplayKit/Layout/ASAbsoluteLayoutSpec.h b/AsyncDisplayKit/Layout/ASAbsoluteLayoutSpec.h index a2b46d921b..5ed9467f47 100644 --- a/AsyncDisplayKit/Layout/ASAbsoluteLayoutSpec.h +++ b/AsyncDisplayKit/Layout/ASAbsoluteLayoutSpec.h @@ -10,15 +10,32 @@ #import +/** How much space the spec will take up. */ +typedef NS_ENUM(NSInteger, ASAbsoluteLayoutSpecSizing) { + /** The spec will take up the maximum size possible. */ + ASAbsoluteLayoutSpecSizingDefault, + /** Computes a size for the spec that is the union of all childrens' frames. */ + ASAbsoluteLayoutSpecSizingSizeToFit, +}; + NS_ASSUME_NONNULL_BEGIN /** - * A layout spec that positions children at fixed positions. - * - * Computes a size that is the union of all childrens' frames. + A layout spec that positions children at fixed positions. */ @interface ASAbsoluteLayoutSpec : ASLayoutSpec +/** + How much space will the spec taken up + */ +@property (nonatomic, assign) ASAbsoluteLayoutSpecSizing sizing; + +/** + @param sizing How much space the spec will take up + @param children Children to be positioned at fixed positions + */ ++ (instancetype)absoluteLayoutSpecWithSizing:(ASAbsoluteLayoutSpecSizing)sizing children:(NSArray> *)children AS_WARN_UNUSED_RESULT; + /** @param children Children to be positioned at fixed positions */ diff --git a/AsyncDisplayKit/Layout/ASAbsoluteLayoutSpec.mm b/AsyncDisplayKit/Layout/ASAbsoluteLayoutSpec.mm index 1fdb527d31..5e6377d66f 100644 --- a/AsyncDisplayKit/Layout/ASAbsoluteLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASAbsoluteLayoutSpec.mm @@ -14,33 +14,54 @@ #import "ASLayoutPrivate.h" #import "ASLayoutElementStylePrivate.h" + +#pragma mark - ASAbsoluteLayoutSpec + @implementation ASAbsoluteLayoutSpec +#pragma mark - Class + + (instancetype)absoluteLayoutSpecWithChildren:(NSArray *)children { return [[self alloc] initWithChildren:children]; } ++ (instancetype)absoluteLayoutSpecWithSizing:(ASAbsoluteLayoutSpecSizing)sizing children:(NSArray> *)children +{ + return [[self alloc] initWithSizing:sizing children:children]; +} + +#pragma mark - Lifecycle + - (instancetype)init { - return [self initWithChildren:@[]]; + return [self initWithChildren:nil]; } - (instancetype)initWithChildren:(NSArray *)children +{ + return [self initWithSizing:ASAbsoluteLayoutSpecSizingDefault children:children]; +} + +- (instancetype)initWithSizing:(ASAbsoluteLayoutSpecSizing)sizing children:(NSArray> *)children { if (!(self = [super init])) { return nil; } + + _sizing = sizing; self.children = children; + return self; } +#pragma mark - ASLayoutSpec + - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize { - // TODO: layout: isValidForLayout() call should not be necessary if INFINITY is used CGSize size = { - (isinf(constrainedSize.max.width) || !ASPointsValidForLayout(constrainedSize.max.width)) ? ASLayoutElementParentDimensionUndefined : constrainedSize.max.width, - (isinf(constrainedSize.max.height) || !ASPointsValidForLayout(constrainedSize.max.height)) ? ASLayoutElementParentDimensionUndefined : constrainedSize.max.height + ASPointsValidForSize(constrainedSize.max.width) == NO ? ASLayoutElementParentDimensionUndefined : constrainedSize.max.width, + ASPointsValidForSize(constrainedSize.max.height) == NO ? ASLayoutElementParentDimensionUndefined : constrainedSize.max.height }; NSArray *children = self.children; @@ -60,14 +81,14 @@ [sublayouts addObject:sublayout]; } - if (isnan(size.width)) { + if (_sizing == ASAbsoluteLayoutSpecSizingSizeToFit || isnan(size.width)) { size.width = constrainedSize.min.width; for (ASLayout *sublayout in sublayouts) { size.width = MAX(size.width, sublayout.position.x + sublayout.size.width); } } - if (isnan(size.height)) { + if (_sizing == ASAbsoluteLayoutSpecSizingSizeToFit || isnan(size.height)) { size.height = constrainedSize.min.height; for (ASLayout *sublayout in sublayouts) { size.height = MAX(size.height, sublayout.position.y + sublayout.size.height);