Skip to content

Commit 7b89a1d

Browse files
hartbitfacebook-github-bot
authored andcommitted
Implemented percentage values in YogaKit
Summary: We still need to wait for the `YGUnitPoint` PR to be merged :) But please let me know what you think. One caveat: because of a limitation of Swift, a literal value can be automatically understood as a point-based `YGValue`, but variables have to be explicitly cast. I haven't found a way around it yet: ``` view.yoga.width = 10 // value == 10, unit == YGUnitPixel let a: CGFloat = 100 view.yoga.height = a // Compiler error view.yoga.height = YGValue(a) // works, not great ``` Closes #390 Reviewed By: emilsjolander Differential Revision: D4954021 Pulled By: maxoll fbshipit-source-id: 5eff6aeb6dd969d0d5dc557b149bb5819b0e31de
1 parent 2035777 commit 7b89a1d

File tree

10 files changed

+346
-245
lines changed

10 files changed

+346
-245
lines changed

YogaKit.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ podspec = Pod::Spec.new do |spec|
1919
spec.ios.frameworks = 'UIKit'
2020

2121
spec.dependency 'Yoga', '~> 1.3'
22-
spec.source_files = 'YogaKit/Source/*.{h,m}'
22+
spec.source_files = 'YogaKit/Source/*.{h,m,swift}'
2323
spec.public_header_files = 'YogaKit/Source/{YGLayout,UIView+Yoga}.h'
2424
spec.private_header_files = 'YogaKit/Source/YGLayout+Private.h'
2525
end

YogaKit/Source/YGLayout.h

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
#import <UIKit/UIKit.h>
1111
#import <yoga/YGEnums.h>
12+
#import <yoga/Yoga.h>
13+
14+
extern YGValue YGPointValue(CGFloat value) NS_SWIFT_UNAVAILABLE("Use the swift Int and FloatingPoint extensions instead");
15+
extern YGValue YGPercentValue(CGFloat value) NS_SWIFT_UNAVAILABLE("Use the swift Int and FloatingPoint extensions instead");
1216

1317
typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
1418
YGDimensionFlexibilityFlexibleWidth = 1 << 0,
@@ -41,34 +45,34 @@ typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
4145

4246
@property (nonatomic, readwrite, assign) CGFloat flexGrow;
4347
@property (nonatomic, readwrite, assign) CGFloat flexShrink;
44-
@property (nonatomic, readwrite, assign) CGFloat flexBasis;
45-
46-
@property (nonatomic, readwrite, assign) CGFloat left;
47-
@property (nonatomic, readwrite, assign) CGFloat top;
48-
@property (nonatomic, readwrite, assign) CGFloat right;
49-
@property (nonatomic, readwrite, assign) CGFloat bottom;
50-
@property (nonatomic, readwrite, assign) CGFloat start;
51-
@property (nonatomic, readwrite, assign) CGFloat end;
52-
53-
@property (nonatomic, readwrite, assign) CGFloat marginLeft;
54-
@property (nonatomic, readwrite, assign) CGFloat marginTop;
55-
@property (nonatomic, readwrite, assign) CGFloat marginRight;
56-
@property (nonatomic, readwrite, assign) CGFloat marginBottom;
57-
@property (nonatomic, readwrite, assign) CGFloat marginStart;
58-
@property (nonatomic, readwrite, assign) CGFloat marginEnd;
59-
@property (nonatomic, readwrite, assign) CGFloat marginHorizontal;
60-
@property (nonatomic, readwrite, assign) CGFloat marginVertical;
61-
@property (nonatomic, readwrite, assign) CGFloat margin;
62-
63-
@property (nonatomic, readwrite, assign) CGFloat paddingLeft;
64-
@property (nonatomic, readwrite, assign) CGFloat paddingTop;
65-
@property (nonatomic, readwrite, assign) CGFloat paddingRight;
66-
@property (nonatomic, readwrite, assign) CGFloat paddingBottom;
67-
@property (nonatomic, readwrite, assign) CGFloat paddingStart;
68-
@property (nonatomic, readwrite, assign) CGFloat paddingEnd;
69-
@property (nonatomic, readwrite, assign) CGFloat paddingHorizontal;
70-
@property (nonatomic, readwrite, assign) CGFloat paddingVertical;
71-
@property (nonatomic, readwrite, assign) CGFloat padding;
48+
@property (nonatomic, readwrite, assign) YGValue flexBasis;
49+
50+
@property (nonatomic, readwrite, assign) YGValue left;
51+
@property (nonatomic, readwrite, assign) YGValue top;
52+
@property (nonatomic, readwrite, assign) YGValue right;
53+
@property (nonatomic, readwrite, assign) YGValue bottom;
54+
@property (nonatomic, readwrite, assign) YGValue start;
55+
@property (nonatomic, readwrite, assign) YGValue end;
56+
57+
@property (nonatomic, readwrite, assign) YGValue marginLeft;
58+
@property (nonatomic, readwrite, assign) YGValue marginTop;
59+
@property (nonatomic, readwrite, assign) YGValue marginRight;
60+
@property (nonatomic, readwrite, assign) YGValue marginBottom;
61+
@property (nonatomic, readwrite, assign) YGValue marginStart;
62+
@property (nonatomic, readwrite, assign) YGValue marginEnd;
63+
@property (nonatomic, readwrite, assign) YGValue marginHorizontal;
64+
@property (nonatomic, readwrite, assign) YGValue marginVertical;
65+
@property (nonatomic, readwrite, assign) YGValue margin;
66+
67+
@property (nonatomic, readwrite, assign) YGValue paddingLeft;
68+
@property (nonatomic, readwrite, assign) YGValue paddingTop;
69+
@property (nonatomic, readwrite, assign) YGValue paddingRight;
70+
@property (nonatomic, readwrite, assign) YGValue paddingBottom;
71+
@property (nonatomic, readwrite, assign) YGValue paddingStart;
72+
@property (nonatomic, readwrite, assign) YGValue paddingEnd;
73+
@property (nonatomic, readwrite, assign) YGValue paddingHorizontal;
74+
@property (nonatomic, readwrite, assign) YGValue paddingVertical;
75+
@property (nonatomic, readwrite, assign) YGValue padding;
7276

7377
@property (nonatomic, readwrite, assign) CGFloat borderLeftWidth;
7478
@property (nonatomic, readwrite, assign) CGFloat borderTopWidth;
@@ -78,12 +82,12 @@ typedef NS_OPTIONS(NSInteger, YGDimensionFlexibility) {
7882
@property (nonatomic, readwrite, assign) CGFloat borderEndWidth;
7983
@property (nonatomic, readwrite, assign) CGFloat borderWidth;
8084

81-
@property (nonatomic, readwrite, assign) CGFloat width;
82-
@property (nonatomic, readwrite, assign) CGFloat height;
83-
@property (nonatomic, readwrite, assign) CGFloat minWidth;
84-
@property (nonatomic, readwrite, assign) CGFloat minHeight;
85-
@property (nonatomic, readwrite, assign) CGFloat maxWidth;
86-
@property (nonatomic, readwrite, assign) CGFloat maxHeight;
85+
@property (nonatomic, readwrite, assign) YGValue width;
86+
@property (nonatomic, readwrite, assign) YGValue height;
87+
@property (nonatomic, readwrite, assign) YGValue minWidth;
88+
@property (nonatomic, readwrite, assign) YGValue minHeight;
89+
@property (nonatomic, readwrite, assign) YGValue maxWidth;
90+
@property (nonatomic, readwrite, assign) YGValue maxHeight;
8791

8892
// Yoga specific properties, not compatible with flexbox specification
8993
@property (nonatomic, readwrite, assign) CGFloat aspectRatio;

YogaKit/Source/YGLayout.m

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,30 @@ - (void)set##capitalized_name:(type)lowercased_name \
2121
YGNodeStyleSet##capitalized_name(self.node, lowercased_name); \
2222
}
2323

24-
#define YG_VALUE_PROPERTY(lowercased_name, capitalized_name) \
25-
- (CGFloat)lowercased_name \
26-
{ \
27-
YGValue value = YGNodeStyleGet##capitalized_name(self.node); \
28-
if (value.unit == YGUnitPoint) { \
29-
return value.value; \
30-
} else { \
31-
return YGUndefined; \
32-
} \
33-
} \
34-
\
35-
- (void)set##capitalized_name:(CGFloat)lowercased_name \
36-
{ \
37-
YGNodeStyleSet##capitalized_name(self.node, lowercased_name); \
24+
#define YG_VALUE_PROPERTY(lowercased_name, capitalized_name) \
25+
- (YGValue)lowercased_name \
26+
{ \
27+
return YGNodeStyleGet##capitalized_name(self.node); \
28+
} \
29+
\
30+
- (void)set##capitalized_name:(YGValue)lowercased_name \
31+
{ \
32+
switch (lowercased_name.unit) { \
33+
case YGUnitPoint: \
34+
YGNodeStyleSet##capitalized_name(self.node, lowercased_name.value); \
35+
break; \
36+
case YGUnitPercent: \
37+
YGNodeStyleSet##capitalized_name##Percent(self.node, lowercased_name.value); \
38+
break; \
39+
default: \
40+
NSAssert(NO, @"Not implemented"); \
41+
} \
3842
}
3943

40-
#define YG_EDGE_PROPERTY_GETTER(lowercased_name, capitalized_name, property, edge) \
41-
- (CGFloat)lowercased_name \
42-
{ \
43-
return YGNodeStyleGet##property(self.node, edge); \
44+
#define YG_EDGE_PROPERTY_GETTER(type, lowercased_name, capitalized_name, property, edge) \
45+
- (type)lowercased_name \
46+
{ \
47+
return YGNodeStyleGet##property(self.node, edge); \
4448
}
4549

4650
#define YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge) \
@@ -49,42 +53,50 @@ - (void)set##capitalized_name:(CGFloat)lowercased_name
4953
YGNodeStyleSet##property(self.node, edge, lowercased_name); \
5054
}
5155

52-
#define YG_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
53-
YG_EDGE_PROPERTY_GETTER(lowercased_name, capitalized_name, property, edge) \
56+
#define YG_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
57+
YG_EDGE_PROPERTY_GETTER(CGFloat, lowercased_name, capitalized_name, property, edge) \
5458
YG_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
5559

56-
#define YG_VALUE_EDGE_PROPERTY_GETTER(objc_lowercased_name, objc_capitalized_name, c_name, edge) \
57-
- (CGFloat)objc_lowercased_name \
58-
{ \
59-
YGValue value = YGNodeStyleGet##c_name(self.node, edge); \
60-
if (value.unit == YGUnitPoint) { \
61-
return value.value; \
62-
} else { \
63-
return YGUndefined; \
64-
} \
65-
}
66-
6760
#define YG_VALUE_EDGE_PROPERTY_SETTER(objc_lowercased_name, objc_capitalized_name, c_name, edge) \
68-
- (void)set##objc_capitalized_name:(CGFloat)objc_lowercased_name \
61+
- (void)set##objc_capitalized_name:(YGValue)objc_lowercased_name \
6962
{ \
70-
YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name); \
63+
switch (objc_lowercased_name.unit) { \
64+
case YGUnitPoint: \
65+
YGNodeStyleSet##c_name(self.node, edge, objc_lowercased_name.value); \
66+
break; \
67+
case YGUnitPercent: \
68+
YGNodeStyleSet##c_name##Percent(self.node, edge, objc_lowercased_name.value); \
69+
break; \
70+
default: \
71+
NSAssert(NO, @"Not implemented"); \
72+
} \
7173
}
7274

73-
#define YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
74-
YG_VALUE_EDGE_PROPERTY_GETTER(lowercased_name, capitalized_name, property, edge) \
75+
#define YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, property, edge) \
76+
YG_EDGE_PROPERTY_GETTER(YGValue, lowercased_name, capitalized_name, property, edge) \
7577
YG_VALUE_EDGE_PROPERTY_SETTER(lowercased_name, capitalized_name, property, edge)
7678

77-
#define YG_VALUE_EDGES_PROPERTIES(lowercased_name, capitalized_name) \
78-
YG_VALUE_EDGE_PROPERTY(lowercased_name##Left, capitalized_name##Left, capitalized_name, YGEdgeLeft) \
79-
YG_VALUE_EDGE_PROPERTY(lowercased_name##Top, capitalized_name##Top, capitalized_name, YGEdgeTop) \
80-
YG_VALUE_EDGE_PROPERTY(lowercased_name##Right, capitalized_name##Right, capitalized_name, YGEdgeRight) \
81-
YG_VALUE_EDGE_PROPERTY(lowercased_name##Bottom, capitalized_name##Bottom, capitalized_name, YGEdgeBottom) \
82-
YG_VALUE_EDGE_PROPERTY(lowercased_name##Start, capitalized_name##Start, capitalized_name, YGEdgeStart) \
83-
YG_VALUE_EDGE_PROPERTY(lowercased_name##End, capitalized_name##End, capitalized_name, YGEdgeEnd) \
79+
#define YG_VALUE_EDGES_PROPERTIES(lowercased_name, capitalized_name) \
80+
YG_VALUE_EDGE_PROPERTY(lowercased_name##Left, capitalized_name##Left, capitalized_name, YGEdgeLeft) \
81+
YG_VALUE_EDGE_PROPERTY(lowercased_name##Top, capitalized_name##Top, capitalized_name, YGEdgeTop) \
82+
YG_VALUE_EDGE_PROPERTY(lowercased_name##Right, capitalized_name##Right, capitalized_name, YGEdgeRight) \
83+
YG_VALUE_EDGE_PROPERTY(lowercased_name##Bottom, capitalized_name##Bottom, capitalized_name, YGEdgeBottom) \
84+
YG_VALUE_EDGE_PROPERTY(lowercased_name##Start, capitalized_name##Start, capitalized_name, YGEdgeStart) \
85+
YG_VALUE_EDGE_PROPERTY(lowercased_name##End, capitalized_name##End, capitalized_name, YGEdgeEnd) \
8486
YG_VALUE_EDGE_PROPERTY(lowercased_name##Horizontal, capitalized_name##Horizontal, capitalized_name, YGEdgeHorizontal) \
8587
YG_VALUE_EDGE_PROPERTY(lowercased_name##Vertical, capitalized_name##Vertical, capitalized_name, YGEdgeVertical) \
8688
YG_VALUE_EDGE_PROPERTY(lowercased_name, capitalized_name, capitalized_name, YGEdgeAll)
8789

90+
YGValue YGPointValue(CGFloat value)
91+
{
92+
return (YGValue) { .value = value, .unit = YGUnitPoint };
93+
}
94+
95+
YGValue YGPercentValue(CGFloat value)
96+
{
97+
return (YGValue) { .value = value, .unit = YGUnitPercent };
98+
}
99+
88100
static YGConfigRef globalConfig;
89101

90102
@interface YGLayout ()
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* Copyright (c) 2014-present, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
postfix operator %
11+
12+
extension Int {
13+
public static postfix func %(value: Int) -> YGValue {
14+
return YGValue(value: Float(value), unit: .percent)
15+
}
16+
}
17+
18+
extension Float {
19+
public static postfix func %(value: Float) -> YGValue {
20+
return YGValue(value: value, unit: .percent)
21+
}
22+
}
23+
24+
extension CGFloat {
25+
public static postfix func %(value: CGFloat) -> YGValue {
26+
return YGValue(value: Float(value), unit: .percent)
27+
}
28+
}
29+
30+
extension YGValue : ExpressibleByIntegerLiteral, ExpressibleByFloatLiteral {
31+
public init(integerLiteral value: Int) {
32+
self = YGValue(value: Float(value), unit: .point)
33+
}
34+
35+
public init(floatLiteral value: Float) {
36+
self = YGValue(value: value, unit: .point)
37+
}
38+
39+
public init(_ value: Float) {
40+
self = YGValue(value: value, unit: .point)
41+
}
42+
43+
public init(_ value: CGFloat) {
44+
self = YGValue(value: Float(value), unit: .point)
45+
}
46+
}

0 commit comments

Comments
 (0)