support flexible top container

Summary:
The main container that gets called `applyLayoutPreservingOrigin:` is using its size as a fixed bounding box.
In some cases it's preferrable to let it accomodate its contents.

This diffs extends `applyLayoutPreservingOrigin:` by adding an additional parameter which can be used to sepecify whether width and/or height are fixed or flexible.

Feel free to suggest better names than `YGDimensionFlexibility` & co.
Let me know if you prefet to kill the API without flexiblity specifier - I'll codemod everything then.

Reviewed By: dshahidehpour

Differential Revision: D4929702

fbshipit-source-id: f128f244140b4a54d8ce3b3f4edddbb9756f8fdf
This commit is contained in:
Martin Kralik
2017-04-23 17:14:05 -07:00
committed by Facebook Github Bot
parent f8a2903d02
commit 849de89a58
3 changed files with 74 additions and 0 deletions

View File

@@ -10,6 +10,11 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import <yoga/YGEnums.h> #import <yoga/YGEnums.h>
typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
YGDimensionFlexibilityFlexibleWidth = 1 << 0,
YGDimensionFlexibilityFlexibleHeigth = 1 << 1,
};
@interface YGLayout : NSObject @interface YGLayout : NSObject
/** /**
@@ -95,6 +100,13 @@
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin - (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin
NS_SWIFT_NAME(applyLayout(preservingOrigin:)); NS_SWIFT_NAME(applyLayout(preservingOrigin:));
/**
Perform a layout calculation and update the frames of the views in the hierarchy with the results.
If the origin is not preserved, the root view's layout results will applied from {0,0}.
*/
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin dimensionFlexibility:(YGDimensionFlexibility)dimensionFlexibility
NS_SWIFT_NAME(applyLayout(preservingOrigin:dimensionFlexibility:));
/** /**
Returns the size of the view if no constraints were given. This could equivalent to calling [self Returns the size of the view if no constraints were given. This could equivalent to calling [self
sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)]; sizeThatFits:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)];

View File

@@ -235,6 +235,20 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio)
YGApplyLayoutToViewHierarchy(self.view, preserveOrigin); YGApplyLayoutToViewHierarchy(self.view, preserveOrigin);
} }
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin dimensionFlexibility:(YGDimensionFlexibility)dimensionFlexibility
{
CGSize size = self.view.bounds.size;
if (dimensionFlexibility & YGDimensionFlexibilityFlexibleWidth) {
size.width = YGUndefined;
}
if (dimensionFlexibility & YGDimensionFlexibilityFlexibleHeigth) {
size.height = YGUndefined;
}
[self calculateLayoutWithSize:size];
YGApplyLayoutToViewHierarchy(self.view, NO);
}
- (CGSize)intrinsicSize - (CGSize)intrinsicSize
{ {
const CGSize constrainedSize = { const CGSize constrainedSize = {

View File

@@ -154,6 +154,54 @@
XCTAssertEqual(25, view2.frame.origin.y); XCTAssertEqual(25, view2.frame.origin.y);
} }
- (void)testContainerWithFlexibleWidthGetsCorrectlySized
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,200,200)];
container.yoga.isEnabled = YES;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.yoga.isEnabled = YES;
view.yoga.width = 100;
view.yoga.height = 100;
[container addSubview:view];
[container.yoga applyLayoutPreservingOrigin:YES dimensionFlexibility:YGDimensionFlexibilityFlexibleWidth];
XCTAssertEqual(100, container.frame.size.width);
XCTAssertEqual(200, container.frame.size.height);
}
- (void)testContainerWithFlexibleHeightGetsCorrectlySized
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,200,200)];
container.yoga.isEnabled = YES;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.yoga.isEnabled = YES;
view.yoga.width = 100;
view.yoga.height = 100;
[container addSubview:view];
[container.yoga applyLayoutPreservingOrigin:YES dimensionFlexibility:YGDimensionFlexibilityFlexibleHeigth];
XCTAssertEqual(200, container.frame.size.width);
XCTAssertEqual(100, container.frame.size.height);
}
- (void)testContainerWithFlexibleWidthAndHeightGetsCorrectlySized
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,200,200)];
container.yoga.isEnabled = YES;
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.yoga.isEnabled = YES;
view.yoga.width = 100;
view.yoga.height = 100;
[container addSubview:view];
[container.yoga applyLayoutPreservingOrigin:YES dimensionFlexibility:YGDimensionFlexibilityFlexibleWidth | YGDimensionFlexibilityFlexibleHeigth];
XCTAssertEqual(100, container.frame.size.width);
XCTAssertEqual(100, container.frame.size.height);
}
- (void)testMarkingDirtyOnlyWorksOnLeafNodes - (void)testMarkingDirtyOnlyWorksOnLeafNodes
{ {
UIView *container = [[UIView alloc] initWithFrame:CGRectZero]; UIView *container = [[UIView alloc] initWithFrame:CGRectZero];