diff --git a/React/Views/RCTShadowView+Layout.h b/React/Views/RCTShadowView+Layout.h index 917b5f4a5..fe40dca40 100644 --- a/React/Views/RCTShadowView+Layout.h +++ b/React/Views/RCTShadowView+Layout.h @@ -11,6 +11,13 @@ #import +/** + * Converts float values between Yoga and CoreGraphics representations, + * especially in terms of edge cases. + */ +RCT_EXTERN float RCTYogaFloatFromCoreGraphicsFloat(CGFloat value); +RCT_EXTERN CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value); + @interface RCTShadowView (Layout) #pragma mark - Computed Layout-Inferred Metrics diff --git a/React/Views/RCTShadowView+Layout.m b/React/Views/RCTShadowView+Layout.m index b5e11e8d6..614a53889 100644 --- a/React/Views/RCTShadowView+Layout.m +++ b/React/Views/RCTShadowView+Layout.m @@ -11,6 +11,32 @@ #import +/** + * Yoga and CoreGraphics have different opinions about how "infinity" value + * should be represented. + * Yoga uses `NAN` which requires additional effort to compare all those values, + * whereas GoreGraphics uses `GFLOAT_MAX` which can be easyly compared with + * standard `==` operator. + */ + +float RCTYogaFloatFromCoreGraphicsFloat(CGFloat value) +{ + if (value == CGFLOAT_MAX || isnan(value) || isinf(value)) { + return YGUndefined; + } + + return value; +} + +CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value) +{ + if (value == YGUndefined || isnan(value) || isinf(value)) { + return CGFLOAT_MAX; + } + + return value; +} + @implementation RCTShadowView (Layout) #pragma mark - Computed Layout-Inferred Metrics @@ -19,10 +45,10 @@ { YGNodeRef yogaNode = self.yogaNode; return (UIEdgeInsets){ - YGNodeLayoutGetPadding(yogaNode, YGEdgeTop), - YGNodeLayoutGetPadding(yogaNode, YGEdgeLeft), - YGNodeLayoutGetPadding(yogaNode, YGEdgeBottom), - YGNodeLayoutGetPadding(yogaNode, YGEdgeRight) + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeTop)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeLeft)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeBottom)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetPadding(yogaNode, YGEdgeRight)) }; } @@ -30,10 +56,10 @@ { YGNodeRef yogaNode = self.yogaNode; return (UIEdgeInsets){ - YGNodeLayoutGetBorder(yogaNode, YGEdgeTop), - YGNodeLayoutGetBorder(yogaNode, YGEdgeLeft), - YGNodeLayoutGetBorder(yogaNode, YGEdgeBottom), - YGNodeLayoutGetBorder(yogaNode, YGEdgeRight) + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeTop)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeLeft)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeBottom)), + RCTCoreGraphicsFloatFromYogaFloat(YGNodeLayoutGetBorder(yogaNode, YGEdgeRight)) }; }