BREAKING: remove css_sizeThatFits:, replace with new API.

Summary: When I try to use this in practice, I have come to realize that css_sizeThatFits will 99% return to you the constrainedSize that you pass it, thus making it useless. Instead, we replace it with a new API that will tell you the optimal size of the resolved layout. From this we can choose to use that size, or scale it down.

Reviewed By: emilsjolander

Differential Revision: D4191873

fbshipit-source-id: d36a2850448d9d82f97e5ef4c7397778c2a14094
This commit is contained in:
Dustin Shahidehpour
2016-11-17 07:29:33 -08:00
committed by Facebook Github Bot
parent 7e4bb732ff
commit 56aa279fef
3 changed files with 56 additions and 33 deletions

View File

@@ -11,10 +11,10 @@
#import "UIView+CSSLayout.h" #import "UIView+CSSLayout.h"
@interface CSSLayoutTests : XCTestCase @interface CSSLayoutKitTests : XCTestCase
@end @end
@implementation CSSLayoutTests @implementation CSSLayoutKitTests
#ifndef TRAVIS_CI #ifndef TRAVIS_CI
@@ -65,21 +65,35 @@
- (void)testSizeThatFitsAsserts - (void)testSizeThatFitsAsserts
{ {
UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
XCTAssertThrows([view css_sizeThatFits:CGSizeZero]);
dispatch_sync(dispatch_queue_create("com.facebook.CSSLayout.testing", DISPATCH_QUEUE_SERIAL), ^(void){ dispatch_sync(dispatch_queue_create("com.facebook.CSSLayout.testing", DISPATCH_QUEUE_SERIAL), ^(void){
XCTAssertThrows([view css_sizeThatFits:CGSizeZero]); XCTAssertThrows([view css_intrinsicSize]);
}); });
} }
- (void)testSizeThatFitsSmoke - (void)testSizeThatFitsSmoke
{ {
UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; UIView *container = [[UIView alloc] initWithFrame:CGRectZero];
[view css_setUsesFlexbox:YES]; [container css_setUsesFlexbox:YES];
[container css_setFlexDirection:CSSFlexDirectionRow];
[container css_setAlignItems:CSSAlignFlexStart];
const CGSize constrainedSize = CGSizeMake(50, 50); UILabel *longTextLabel = [[UILabel alloc] initWithFrame:CGRectZero];
const CGSize actualSize = [view css_sizeThatFits:constrainedSize]; longTextLabel.text = @"This is a very very very very very very very very long piece of text.";
XCTAssertTrue(CGSizeEqualToSize(constrainedSize, actualSize), @"Actual Size: %@", NSStringFromCGSize(actualSize)); longTextLabel.lineBreakMode = NSLineBreakByTruncatingTail;
longTextLabel.numberOfLines = 1;
[longTextLabel css_setUsesFlexbox:YES];
[longTextLabel css_setFlexShrink:1];
[container addSubview:longTextLabel];
UIView *textBadgeView = [[UIView alloc] initWithFrame:CGRectZero];
[textBadgeView css_setUsesFlexbox:YES];
[textBadgeView css_setMargin:3.0 forEdge:CSSEdgeLeft];
[textBadgeView css_setWidth:10];
[textBadgeView css_setHeight:10];
[container addSubview:textBadgeView];
const CGSize containerSize = [container css_intrinsicSize];
XCTAssertTrue(CGSizeEqualToSize(CGSizeMake(514,21), containerSize), @"Size is actually %@", NSStringFromCGSize(containerSize));
} }
- (void)testFrameAndOriginPlacement - (void)testFrameAndOriginPlacement

View File

@@ -52,8 +52,8 @@
- (void)css_applyLayout; - (void)css_applyLayout;
/** /**
Compute the size of a layout with a constrained size. Returns the size of the view if no constraints were given. This could equivalent to calling [self sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)];
*/ */
- (CGSize)css_sizeThatFits:(CGSize)constrainedSize; - (CGSize)css_intrinsicSize;
@end @end

View File

@@ -157,32 +157,21 @@
return CSSNodeLayoutGetDirection([self cssNode]); return CSSNodeLayoutGetDirection([self cssNode]);
} }
- (CGSize)css_sizeThatFits:(CGSize)constrainedSize
{
NSAssert([NSThread isMainThread], @"CSS Layout calculation must be done on main.");
NSAssert([self css_usesFlexbox], @"CSS Layout is not enabled for this view.");
CSSAttachNodesFromViewHierachy(self);
const CSSNodeRef node = [self cssNode];
CSSNodeCalculateLayout(
node,
constrainedSize.width,
constrainedSize.height,
CSSNodeStyleGetDirection(node));
return (CGSize) {
.width = CSSNodeLayoutGetWidth(node),
.height = CSSNodeLayoutGetHeight(node),
};
}
- (void)css_applyLayout - (void)css_applyLayout
{ {
[self css_sizeThatFits:self.bounds.size]; [self calculateLayoutWithSize:self.bounds.size];
CSSApplyLayoutToViewHierarchy(self); CSSApplyLayoutToViewHierarchy(self);
} }
- (CGSize)css_intrinsicSize
{
const CGSize constrainedSize = {
.width = CSSUndefined,
.height = CSSUndefined,
};
return [self calculateLayoutWithSize:constrainedSize];
}
#pragma mark - Private #pragma mark - Private
- (CSSNodeRef)cssNode - (CSSNodeRef)cssNode
@@ -197,6 +186,26 @@
return node.cnode; return node.cnode;
} }
- (CGSize)calculateLayoutWithSize:(CGSize)size
{
NSAssert([NSThread isMainThread], @"CSS Layout calculation must be done on main.");
NSAssert([self css_usesFlexbox], @"CSS Layout is not enabled for this view.");
CSSAttachNodesFromViewHierachy(self);
const CSSNodeRef node = [self cssNode];
CSSNodeCalculateLayout(
node,
size.width,
size.height,
CSSNodeStyleGetDirection(node));
return (CGSize) {
.width = CSSNodeLayoutGetWidth(node),
.height = CSSNodeLayoutGetHeight(node),
};
}
static CSSSize CSSMeasureView( static CSSSize CSSMeasureView(
CSSNodeRef node, CSSNodeRef node,
float width, float width,