diff --git a/AsyncDisplayKit/Layout/ASLayoutElement.h b/AsyncDisplayKit/Layout/ASLayoutElement.h index e933ee36e3..b55aeb0c2c 100644 --- a/AsyncDisplayKit/Layout/ASLayoutElement.h +++ b/AsyncDisplayKit/Layout/ASLayoutElement.h @@ -250,10 +250,11 @@ extern NSString * const ASLayoutElementStyleLayoutPositionProperty; * @discussion This method is optional, but one of either preferredSize or preferredLayoutSize is required * for nodes that either have no intrinsic content size or * should be laid out at a different size than its intrinsic content size. For example, this property could be - * set on an ASImageNode to display at a size different from the underlying image size. + * set on an ASImageNode to display at a size different from the underlying image size. + * + * @warning Calling the getter when the size's width or height are relative will cause an assert. */ @property (nonatomic, assign) CGSize preferredSize; -- (CGSize)preferredSize UNAVAILABLE_ATTRIBUTE; /** * @abstract An optional property that provides a minimum size bound for a layout element. If provided, this restriction will diff --git a/AsyncDisplayKit/Layout/ASLayoutElement.mm b/AsyncDisplayKit/Layout/ASLayoutElement.mm index a0761324b1..2f563124da 100644 --- a/AsyncDisplayKit/Layout/ASLayoutElement.mm +++ b/AsyncDisplayKit/Layout/ASLayoutElement.mm @@ -254,6 +254,22 @@ do {\ ASLayoutElementStyleCallDelegate(ASLayoutElementStyleHeightProperty); } +- (CGSize)preferredSize +{ + ASDN::MutexLocker l(__instanceLock__); + if (_size.width.unit != ASDimensionUnitPoints) { + NSCAssert(NO, @"Cannot get preferredSize of element with fractional width. Width: %@.", NSStringFromASDimension(_size.width)); + return CGSizeZero; + } + + if (_size.height.unit != ASDimensionUnitPoints) { + NSCAssert(NO, @"Cannot get preferredSize of element with fractional height. Height: %@.", NSStringFromASDimension(_size.height)); + return CGSizeZero; + } + + return CGSizeMake(_size.width.value, _size.height.value); +} + - (void)setMinSize:(CGSize)minSize { ASDN::MutexLocker l(__instanceLock__); diff --git a/AsyncDisplayKitTests/ASLayoutElementStyleTests.m b/AsyncDisplayKitTests/ASLayoutElementStyleTests.m index 6f4caabebb..e2551f6cfd 100644 --- a/AsyncDisplayKitTests/ASLayoutElementStyleTests.m +++ b/AsyncDisplayKitTests/ASLayoutElementStyleTests.m @@ -8,7 +8,7 @@ // of patent rights can be found in the PATENTS file in the same directory. // -#import +#import "ASXCTExtensions.h" #import "ASLayoutElement.h" #pragma mark - ASLayoutElementStyleTestsDelegate @@ -61,6 +61,7 @@ CGSize size = CGSizeMake(100, 100); style.preferredSize = size; + ASXCTAssertEqualSizes(style.preferredSize, size); XCTAssertTrue(ASDimensionEqualToDimension(style.width, ASDimensionMakeWithPoints(size.width))); XCTAssertTrue(ASDimensionEqualToDimension(style.height, ASDimensionMakeWithPoints(size.height))); @@ -73,6 +74,19 @@ XCTAssertTrue(ASDimensionEqualToDimension(style.maxHeight, ASDimensionMakeWithPoints(size.height))); } +- (void)testReadingInvalidSizeForPreferredSize +{ + ASLayoutElementStyle *style = [ASLayoutElementStyle new]; + + XCTAssertThrows(style.preferredSize); + + style.width = ASDimensionMake(ASDimensionUnitFraction, 0.5); + XCTAssertThrows(style.preferredSize); + + style.preferredSize = CGSizeMake(100, 100); + XCTAssertNoThrow(style.preferredSize); +} + - (void)testSettingSizeViaLayoutSize { ASLayoutElementStyle *style = [ASLayoutElementStyle new];