BREAKING CHANGE: rename applyLayout to applyLayoutPreservingOrigin.

Summary: Will update on Monday

Reviewed By: emilsjolander

Differential Revision: D4545786

fbshipit-source-id: f8189d82f1c64cd1eac532fd2dfaa9aea35d6004
This commit is contained in:
Dustin Shahidehpour
2017-02-11 11:16:14 -08:00
committed by Facebook Github Bot
parent 063f65d065
commit 4f6924a0c1
8 changed files with 91 additions and 76 deletions

23
YogaKit/CHANGELOG.md Normal file
View File

@@ -0,0 +1,23 @@
# CHANGELOG
The changelog for `YogaKit`.
1.2.0 (**upcoming release**)
-----
### Breaking Changes
- `applyLayout()` has now been changed to `applyLayout(preservingOrigin:)`.
- Computed properties are no longer reflected in getter's of the affected properties.
```swift
// OLD
view.yoga.margin = 10
view.yoga.marginTop // 10
view.yoga.marginLeft // 10
// NEW
view.yoga.margin = 10
view.yoga.marginTop // 0
view.yoga.marginLeft // 0
```

View File

@@ -89,9 +89,10 @@
@property (nonatomic, readonly, assign) YGDirection resolvedDirection; @property (nonatomic, readonly, assign) YGDirection resolvedDirection;
/** /**
Perform a layout calculation and update the frames of the views in the hierarchy with the results 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)applyLayout NS_SWIFT_NAME(applyLayout()); - (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin NS_SWIFT_NAME(applyLayout(preservingOrigin:));
/** /**
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

View File

@@ -208,7 +208,13 @@ YG_PROPERTY(CGFloat, aspectRatio, AspectRatio)
- (void)applyLayout - (void)applyLayout
{ {
[self calculateLayoutWithSize:self.view.bounds.size]; [self calculateLayoutWithSize:self.view.bounds.size];
YGApplyLayoutToViewHierarchy(self.view, YES); YGApplyLayoutToViewHierarchy(self.view, NO);
}
- (void)applyLayoutPreservingOrigin:(BOOL)preserveOrigin
{
[self calculateLayoutWithSize:self.view.bounds.size];
YGApplyLayoutToViewHierarchy(self.view, preserveOrigin);
} }
- (CGSize)intrinsicSize - (CGSize)intrinsicSize

View File

@@ -109,6 +109,31 @@
XCTAssertEqual(longTextLabelSize.width + textBadgeView.yoga.intrinsicSize.width, containerSize.width); XCTAssertEqual(longTextLabelSize.width + textBadgeView.yoga.intrinsicSize.width, containerSize.width);
} }
- (void)testPreservingOrigin
{
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0,0,50,75)];
container.yoga.isEnabled = YES;
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.yoga.isEnabled = YES;
view.yoga.flexBasis = 0;
view.yoga.flexGrow = 1;
[container addSubview:view];
UIView *view2 = [[UIView alloc] initWithFrame:CGRectZero];
view2.yoga.isEnabled = YES;
view2.yoga.marginTop = 25;
view2.yoga.flexBasis = 0;
view2.yoga.flexGrow = 1;
[container addSubview:view2];
[container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(50, view2.frame.origin.y);
[view2.yoga applyLayoutPreservingOrigin:NO];
XCTAssertEqual(25, view2.frame.origin.y);
}
- (void)testThatMarkingLeafsAsDirtyWillTriggerASizeRecalculation - (void)testThatMarkingLeafsAsDirtyWillTriggerASizeRecalculation
{ {
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 50)]; UIView *container = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 500, 50)];
@@ -116,22 +141,22 @@
container.yoga.flexDirection = YGFlexDirectionRow; container.yoga.flexDirection = YGFlexDirectionRow;
container.yoga.alignItems = YGAlignFlexStart; container.yoga.alignItems = YGAlignFlexStart;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero]; UILabel *view = [[UILabel alloc] initWithFrame:CGRectZero];
label.text = @"This is a short text."; view.text = @"This is a short text.";
label.numberOfLines = 1; view.numberOfLines = 1;
label.yoga.isEnabled = YES; view.yoga.isEnabled = YES;
[container addSubview:label]; [container addSubview:view];
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
CGSize const labelSizeAfterFirstPass = label.frame.size; CGSize const viewSizeAfterFirstPass = view.frame.size;
label.text = @"This is a slightly longer text."; view.text = @"This is a slightly longer text.";
XCTAssertTrue(CGSizeEqualToSize(label.frame.size, labelSizeAfterFirstPass)); XCTAssertTrue(CGSizeEqualToSize(view.frame.size, viewSizeAfterFirstPass));
[label.yoga markDirty]; [view.yoga markDirty];
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertFalse(CGSizeEqualToSize(label.frame.size, labelSizeAfterFirstPass)); XCTAssertFalse(CGSizeEqualToSize(view.frame.size, viewSizeAfterFirstPass));
} }
- (void)testFrameAndOriginPlacement - (void)testFrameAndOriginPlacement
@@ -157,7 +182,7 @@
subview3.yoga.flexGrow = 1; subview3.yoga.flexGrow = 1;
[container addSubview:subview3]; [container addSubview:subview3];
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqualWithAccuracy(subview2.frame.origin.x, CGRectGetMaxX(subview1.frame), FLT_EPSILON); XCTAssertEqualWithAccuracy(subview2.frame.origin.x, CGRectGetMaxX(subview1.frame), FLT_EPSILON);
XCTAssertEqualWithAccuracy(subview3.frame.origin.x, CGRectGetMaxX(subview2.frame), FLT_EPSILON); XCTAssertEqualWithAccuracy(subview3.frame.origin.x, CGRectGetMaxX(subview2.frame), FLT_EPSILON);
@@ -193,7 +218,7 @@
subview3.yoga.flexGrow = 1; subview3.yoga.flexGrow = 1;
[container addSubview:subview3]; [container addSubview:subview3];
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertTrue(CGRectEqualToRect(subview1.frame, CGRectMake(0, 0, 100, 50))); XCTAssertTrue(CGRectEqualToRect(subview1.frame, CGRectMake(0, 0, 100, 50)));
XCTAssertTrue(CGRectEqualToRect(subview2.frame, CGRectMake(100, 0, 100, 50))); XCTAssertTrue(CGRectEqualToRect(subview2.frame, CGRectMake(100, 0, 100, 50)));
@@ -201,7 +226,7 @@
[container exchangeSubviewAtIndex:2 withSubviewAtIndex:0]; [container exchangeSubviewAtIndex:2 withSubviewAtIndex:0];
subview2.yoga.isIncludedInLayout = NO; subview2.yoga.isIncludedInLayout = NO;
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertTrue(CGRectEqualToRect(subview3.frame, CGRectMake(0, 0, 150, 50))); XCTAssertTrue(CGRectEqualToRect(subview3.frame, CGRectMake(0, 0, 150, 50)));
XCTAssertTrue(CGRectEqualToRect(subview1.frame, CGRectMake(150, 0, 150, 50))); XCTAssertTrue(CGRectEqualToRect(subview1.frame, CGRectMake(150, 0, 150, 50)));
@@ -233,14 +258,14 @@
subview3.yoga.flexGrow = 1; subview3.yoga.flexGrow = 1;
[container addSubview:subview3]; [container addSubview:subview3];
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
for (UIView *subview in container.subviews) { for (UIView *subview in container.subviews) {
XCTAssertEqual(subview.bounds.size.width, 100); XCTAssertEqual(subview.bounds.size.width, 100);
} }
subview3.yoga.isIncludedInLayout = NO; subview3.yoga.isIncludedInLayout = NO;
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(subview1.bounds.size.width, 150); XCTAssertEqual(subview1.bounds.size.width, 150);
XCTAssertEqual(subview2.bounds.size.width, 150); XCTAssertEqual(subview2.bounds.size.width, 150);
@@ -270,11 +295,11 @@
subview3.yoga.isIncludedInLayout = YES; subview3.yoga.isIncludedInLayout = YES;
[container addSubview:subview3]; [container addSubview:subview3];
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(container.yoga.numberOfChildren, 1); XCTAssertEqual(container.yoga.numberOfChildren, 1);
subview2.yoga.isIncludedInLayout = YES; subview2.yoga.isIncludedInLayout = YES;
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(container.yoga.numberOfChildren, 2); XCTAssertEqual(container.yoga.numberOfChildren, 2);
} }
@@ -300,14 +325,14 @@
subview3.yoga.isIncludedInLayout = NO; subview3.yoga.isIncludedInLayout = NO;
[container addSubview:subview3]; [container addSubview:subview3];
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(subview1.bounds.size.width, 150); XCTAssertEqual(subview1.bounds.size.width, 150);
XCTAssertEqual(subview2.bounds.size.width, 150); XCTAssertEqual(subview2.bounds.size.width, 150);
XCTAssertEqual(subview3.bounds.size.width, 0); XCTAssertEqual(subview3.bounds.size.width, 0);
subview3.yoga.isIncludedInLayout = YES; subview3.yoga.isIncludedInLayout = YES;
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(subview1.bounds.size.width, 100); XCTAssertEqual(subview1.bounds.size.width, 100);
XCTAssertEqual(subview2.bounds.size.width, 100); XCTAssertEqual(subview2.bounds.size.width, 100);
@@ -361,7 +386,7 @@
someView.yoga.flexGrow = 1; someView.yoga.flexGrow = 1;
[view addSubview:someView]; [view addSubview:someView];
} }
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
// Add the same amount of new views, reapply layout. // Add the same amount of new views, reapply layout.
for (UIView *view in @[subview1, subview2]) { for (UIView *view in @[subview1, subview2]) {
@@ -370,7 +395,7 @@
someView.yoga.flexGrow = 1; someView.yoga.flexGrow = 1;
[view addSubview:someView]; [view addSubview:someView];
} }
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
XCTAssertEqual(subview1.bounds.size.width, 100); XCTAssertEqual(subview1.bounds.size.width, 100);
XCTAssertEqual(subview1.bounds.size.height, 25); XCTAssertEqual(subview1.bounds.size.height, 25);
@@ -406,9 +431,9 @@
subview2.yoga.isEnabled = YES; subview2.yoga.isEnabled = YES;
[subview1 addSubview:subview2]; [subview1 addSubview:subview2];
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
[subview2 removeFromSuperview]; [subview2 removeFromSuperview];
[container.yoga applyLayout]; [container.yoga applyLayoutPreservingOrigin:YES];
} }
- (void)testPositionalPropertiesWork - (void)testPositionalPropertiesWork
@@ -594,40 +619,4 @@
XCTAssertEqual(view.yoga.borderEndWidth, 7); XCTAssertEqual(view.yoga.borderEndWidth, 7);
} }
- (void)testOriginIsPreservedOnRootOfLayout
{
const CGSize containerSize = CGSizeMake(200, 50);
UIView *container = [[UIView alloc] initWithFrame:CGRectMake(10, 10, containerSize.width, containerSize.height)];
container.yoga.isEnabled = YES;
container.yoga.flexDirection = YGFlexDirectionRow;
UIView *subview1 = [[UIView alloc] initWithFrame:CGRectZero];
subview1.yoga.isEnabled = YES;
subview1.yoga.flexGrow = 1;
[container addSubview:subview1];
UIView *subview2 = [[UIView alloc] initWithFrame:CGRectZero];
subview2.yoga.isEnabled = YES;
subview2.yoga.flexGrow = 1;
subview2.yoga.flexDirection = YGFlexDirectionColumn;
subview2.yoga.marginLeft = 10;
[container addSubview:subview2];
[container.yoga applyLayout];
XCTAssertTrue(CGRectEqualToRect(container.frame, CGRectMake(10, 10, 200, 50)));
XCTAssertTrue(CGRectEqualToRect(subview1.frame, CGRectMake(0, 0, 95, 50)));
XCTAssertTrue(CGRectEqualToRect(subview2.frame, CGRectMake(105, 0, 95, 50)));
UIView *subview3 = [[UIView alloc] initWithFrame:CGRectZero];
subview3.yoga.isEnabled = YES;
subview3.yoga.alignSelf = YGAlignFlexEnd;
subview3.yoga.height = 50;
[subview2 addSubview:subview3];
[subview2.yoga applyLayout];
XCTAssertTrue(CGRectEqualToRect(subview2.frame, CGRectMake(115, 0, 85, 50)));
XCTAssertTrue(CGRectEqualToRect(subview3.frame, CGRectMake(85,0,0,50)));
}
@end @end

View File

@@ -1,7 +1,7 @@
PODS: PODS:
- Yoga (1.0.2) - Yoga (1.1.0)
- YogaKit (1.0.3): - YogaKit (1.1.0):
- Yoga (~> 1.0) - Yoga (~> 1.1)
DEPENDENCIES: DEPENDENCIES:
- YogaKit (from `../../YogaKit.podspec`) - YogaKit (from `../../YogaKit.podspec`)
@@ -11,8 +11,8 @@ EXTERNAL SOURCES:
:path: "../../YogaKit.podspec" :path: "../../YogaKit.podspec"
SPEC CHECKSUMS: SPEC CHECKSUMS:
Yoga: ef42f88b9bcbd7daf7267c0f19d8636ce3a50618 Yoga: 0bf083b7c485b20598020dbedcea869cbe53071e
YogaKit: 6d9826a015c029b13731a33bf96fe6c1e33748a6 YogaKit: 80df90de9ef2900baa111f2c93476a6f9e921385
PODFILE CHECKSUM: 9db3bdea7f1b4b715ad859a449b2dc87fb6226cc PODFILE CHECKSUM: 9db3bdea7f1b4b715ad859a449b2dc87fb6226cc

View File

@@ -36,6 +36,6 @@ class SwiftViewController: UIViewController {
child2.addSubview(child3) child2.addSubview(child3)
root.addSubview(child1) root.addSubview(child1)
root.addSubview(child2) root.addSubview(child2)
root.yoga.applyLayout() root.yoga.applyLayout(preservingOrigin: false)
} }
} }

View File

@@ -10,10 +10,6 @@
#import <YogaKit/UIView+Yoga.h> #import <YogaKit/UIView+Yoga.h>
@interface ViewController ()
@end
@implementation ViewController @implementation ViewController
- (void)viewDidLoad - (void)viewDidLoad
@@ -53,7 +49,7 @@
[child2 addSubview:child3]; [child2 addSubview:child3];
[root addSubview:child1]; [root addSubview:child1];
[root addSubview:child2]; [root addSubview:child2];
[root.yoga applyLayout]; [root.yoga applyLayoutPreservingOrigin:NO];
} }

View File

@@ -22,6 +22,6 @@ Yoga relies on `UIView` subviews to build up its internal layout tree. However,
It is also possible to query the number of children **included** in layout via `numberOfChildren`. It is also possible to query the number of children **included** in layout via `numberOfChildren`.
### Layout ### Layout
To apply a layout to a view (and its' subviews) you need to call `[view.yoga applyLayout]`. This will do a layout calculation (if needed) and apply the calculated frames to every view included in the layout. To apply a layout to a view (and its' subviews) you need to call `[view.yoga applyLayoutPreservingOrigin:NO]`. This will do a layout calculation (if needed) and apply the calculated frames to every view included in the layout.
In the event that you need to another layout pass on a view you can mark it dirty via `[view.yoga markDirty]`. In the event that you need to another layout pass on a view you can mark it dirty via `[view.yoga markDirty]`.