Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatible with react-native 0.76 on iOS due to border radii #125

Open
jparkrr opened this issue Dec 4, 2024 · 4 comments
Open

Incompatible with react-native 0.76 on iOS due to border radii #125

jparkrr opened this issue Dec 4, 2024 · 4 comments

Comments

@jparkrr
Copy link

jparkrr commented Dec 4, 2024

There were some changes to RCTCornerRadii in 0.76: facebook/react-native#46009. This causes this package to error during compilation for iOS.

I made a quick patch with patch-package. I've done some brief tests and it seems to work. This assumes all your border radii are symmetric, so a real PR would need to take asymmetric values into account. Also this patch is not backwards compatible.

patches/react-native-shared-element+0.8.9.patch:

diff --git a/node_modules/react-native-shared-element/ios/RNSharedElementCornerRadii.m b/node_modules/react-native-shared-element/ios/RNSharedElementCornerRadii.m
index 5060067..413281a 100644
--- a/node_modules/react-native-shared-element/ios/RNSharedElementCornerRadii.m
+++ b/node_modules/react-native-shared-element/ios/RNSharedElementCornerRadii.m
@@ -69,8 +69,8 @@ static CGFloat RNSharedElementDefaultIfNegativeTo(CGFloat defaultValue, CGFloat
   CALayer *mask = nil;
   CGFloat cornerRadius = 0;
   
-  if (RCTCornerRadiiAreEqual(radii)) {
-    cornerRadius = radii.topLeft;
+  if (RCTCornerRadiiAreEqualAndSymmetrical(radii)) {
+    cornerRadius = radii.topLeftHorizontal;
   } else {
     CAShapeLayer *shapeLayer = [CAShapeLayer layer];
     RCTCornerInsets cornerInsets = RCTGetCornerInsets(radii, UIEdgeInsetsZero);
@@ -121,36 +121,52 @@ static CGFloat RNSharedElementDefaultIfNegativeTo(CGFloat defaultValue, CGFloat
     const CGFloat directionAwareBottomLeftRadius = isRTL ? bottomEndRadius : bottomStartRadius;
     const CGFloat directionAwareBottomRightRadius = isRTL ? bottomStartRadius : bottomEndRadius;
     
-    result.topLeft = RNSharedElementDefaultIfNegativeTo(radius, directionAwareTopLeftRadius);
-    result.topRight = RNSharedElementDefaultIfNegativeTo(radius, directionAwareTopRightRadius);
-    result.bottomLeft = RNSharedElementDefaultIfNegativeTo(radius, directionAwareBottomLeftRadius);
-    result.bottomRight = RNSharedElementDefaultIfNegativeTo(radius, directionAwareBottomRightRadius);
+    result.topLeftHorizontal = RNSharedElementDefaultIfNegativeTo(radius, directionAwareTopLeftRadius);
+    result.topRightHorizontal = RNSharedElementDefaultIfNegativeTo(radius, directionAwareTopRightRadius);
+    result.bottomLeftHorizontal = RNSharedElementDefaultIfNegativeTo(radius, directionAwareBottomLeftRadius);
+    result.bottomRightHorizontal = RNSharedElementDefaultIfNegativeTo(radius, directionAwareBottomRightRadius);
+    result.topLeftVertical = RNSharedElementDefaultIfNegativeTo(radius, directionAwareTopLeftRadius);
+    result.topRightVertical = RNSharedElementDefaultIfNegativeTo(radius, directionAwareTopRightRadius);
+    result.bottomLeftVertical = RNSharedElementDefaultIfNegativeTo(radius, directionAwareBottomLeftRadius);
+    result.bottomRightVertical = RNSharedElementDefaultIfNegativeTo(radius, directionAwareBottomRightRadius);
   } else {
     const CGFloat directionAwareTopLeftRadius = isRTL ? _radii[RNSharedElementCornerTopEnd] : _radii[RNSharedElementCornerTopStart];
     const CGFloat directionAwareTopRightRadius = isRTL ? _radii[RNSharedElementCornerTopStart] : _radii[RNSharedElementCornerTopEnd];
     const CGFloat directionAwareBottomLeftRadius = isRTL ? _radii[RNSharedElementCornerBottomEnd] : _radii[RNSharedElementCornerBottomStart];
     const CGFloat directionAwareBottomRightRadius = isRTL ? _radii[RNSharedElementCornerBottomStart] : _radii[RNSharedElementCornerBottomEnd];
     
-    result.topLeft =
+    result.topLeftHorizontal =
     RNSharedElementDefaultIfNegativeTo(radius, RNSharedElementDefaultIfNegativeTo(_radii[RNSharedElementCornerTopLeft], directionAwareTopLeftRadius));
-    result.topRight =
+    result.topRightHorizontal =
     RNSharedElementDefaultIfNegativeTo(radius, RNSharedElementDefaultIfNegativeTo(_radii[RNSharedElementCornerTopRight], directionAwareTopRightRadius));
-    result.bottomLeft =
+    result.bottomLeftHorizontal =
     RNSharedElementDefaultIfNegativeTo(radius, RNSharedElementDefaultIfNegativeTo(_radii[RNSharedElementCornerBottomLeft], directionAwareBottomLeftRadius));
-    result.bottomRight = RNSharedElementDefaultIfNegativeTo(
+    result.bottomRightHorizontal = RNSharedElementDefaultIfNegativeTo(
+                                                            radius, RNSharedElementDefaultIfNegativeTo(_radii[RNSharedElementCornerBottomRight], directionAwareBottomRightRadius));
+    result.topLeftVertical =
+    RNSharedElementDefaultIfNegativeTo(radius, RNSharedElementDefaultIfNegativeTo(_radii[RNSharedElementCornerTopLeft], directionAwareTopLeftRadius));
+    result.topRightVertical =
+    RNSharedElementDefaultIfNegativeTo(radius, RNSharedElementDefaultIfNegativeTo(_radii[RNSharedElementCornerTopRight], directionAwareTopRightRadius));
+    result.bottomLeftVertical =
+    RNSharedElementDefaultIfNegativeTo(radius, RNSharedElementDefaultIfNegativeTo(_radii[RNSharedElementCornerBottomLeft], directionAwareBottomLeftRadius));
+    result.bottomRightVertical = RNSharedElementDefaultIfNegativeTo(
                                                             radius, RNSharedElementDefaultIfNegativeTo(_radii[RNSharedElementCornerBottomRight], directionAwareBottomRightRadius));
   }
   
   // Get scale factors required to prevent radii from overlapping
-  const CGFloat topScaleFactor = RCTZeroIfNaN(MIN(1, bounds.size.width / (result.topLeft + result.topRight)));
-  const CGFloat bottomScaleFactor = RCTZeroIfNaN(MIN(1, bounds.size.width / (result.bottomLeft + result.bottomRight)));
-  const CGFloat rightScaleFactor = RCTZeroIfNaN(MIN(1, bounds.size.height / (result.topRight + result.bottomRight)));
-  const CGFloat leftScaleFactor = RCTZeroIfNaN(MIN(1, bounds.size.height / (result.topLeft + result.bottomLeft)));
-  
-  result.topLeft *= MIN(topScaleFactor, leftScaleFactor);
-  result.topRight *= MIN(topScaleFactor, rightScaleFactor);
-  result.bottomLeft *= MIN(bottomScaleFactor, leftScaleFactor);
-  result.bottomRight *= MIN(bottomScaleFactor, rightScaleFactor);
+  const CGFloat topScaleFactor = RCTZeroIfNaN(MIN(1, bounds.size.width / (result.topLeftHorizontal + result.topRightHorizontal)));
+  const CGFloat bottomScaleFactor = RCTZeroIfNaN(MIN(1, bounds.size.width / (result.bottomLeftHorizontal + result.bottomRightHorizontal)));
+  const CGFloat rightScaleFactor = RCTZeroIfNaN(MIN(1, bounds.size.height / (result.topRightHorizontal + result.bottomRightHorizontal)));
+  const CGFloat leftScaleFactor = RCTZeroIfNaN(MIN(1, bounds.size.height / (result.topLeftHorizontal + result.bottomLeftHorizontal)));
+  
+  result.topLeftHorizontal *= MIN(topScaleFactor, leftScaleFactor);
+  result.topRightHorizontal *= MIN(topScaleFactor, rightScaleFactor);
+  result.bottomLeftHorizontal *= MIN(bottomScaleFactor, leftScaleFactor);
+  result.bottomRightHorizontal *= MIN(bottomScaleFactor, rightScaleFactor);
+  result.topLeftVertical *= MIN(topScaleFactor, leftScaleFactor);
+  result.topRightVertical *= MIN(topScaleFactor, rightScaleFactor);
+  result.bottomLeftVertical *= MIN(bottomScaleFactor, leftScaleFactor);
+  result.bottomRightVertical *= MIN(bottomScaleFactor, rightScaleFactor);
   
   _cachedBounds = bounds;
   _cachedRadii = result;
diff --git a/node_modules/react-native-shared-element/ios/RNSharedElementStyle.m b/node_modules/react-native-shared-element/ios/RNSharedElementStyle.m
index 9f65b9d..6ae25d8 100644
--- a/node_modules/react-native-shared-element/ios/RNSharedElementStyle.m
+++ b/node_modules/react-native-shared-element/ios/RNSharedElementStyle.m
@@ -112,10 +112,10 @@
   CGRect radiiRect = CGRectMake(0, 0, 1000000, 1000000);
   RCTCornerRadii radii1 = [style1.cornerRadii radiiForBounds:radiiRect];
   RCTCornerRadii radii2 = [style2.cornerRadii radiiForBounds:radiiRect];
-  [style.cornerRadii setRadius:radii1.topLeft + ((radii2.topLeft - radii1.topLeft) * position) corner:RNSharedElementCornerTopLeft];
-  [style.cornerRadii setRadius:radii1.topRight + ((radii2.topRight - radii1.topRight) * position) corner:RNSharedElementCornerTopRight];
-  [style.cornerRadii setRadius:radii1.bottomLeft + ((radii2.bottomLeft - radii1.bottomLeft) * position) corner:RNSharedElementCornerBottomLeft];
-  [style.cornerRadii setRadius:radii1.bottomRight + ((radii2.bottomRight - radii1.bottomRight) * position) corner:RNSharedElementCornerBottomRight];
+  [style.cornerRadii setRadius:radii1.topLeftHorizontal + ((radii2.topLeftHorizontal - radii1.topLeftHorizontal) * position) corner:RNSharedElementCornerTopLeft];
+  [style.cornerRadii setRadius:radii1.topRightHorizontal + ((radii2.topRightHorizontal - radii1.topRightHorizontal) * position) corner:RNSharedElementCornerTopRight];
+  [style.cornerRadii setRadius:radii1.bottomLeftHorizontal + ((radii2.bottomLeftHorizontal - radii1.bottomLeftHorizontal) * position) corner:RNSharedElementCornerBottomLeft];
+  [style.cornerRadii setRadius:radii1.bottomRightHorizontal + ((radii2.bottomRightHorizontal - radii1.bottomRightHorizontal) * position) corner:RNSharedElementCornerBottomRight];
   
   style.borderWidth = style1.borderWidth + ((style2.borderWidth - style1.borderWidth) * position);
   style.borderColor = [RNSharedElementStyle getInterpolatedColor:style1.borderColor color2:style2.borderColor position:position];
diff --git a/node_modules/react-native-shared-element/ios/RNSharedElementTransition.m b/node_modules/react-native-shared-element/ios/RNSharedElementTransition.m
index 97de533..dbd1d66 100644
--- a/node_modules/react-native-shared-element/ios/RNSharedElementTransition.m
+++ b/node_modules/react-native-shared-element/ios/RNSharedElementTransition.m
@@ -388,10 +388,10 @@
     },
     @"contentType": item.content ? item.content.typeName : @"none",
     @"style": @{
-        @"borderTopLeftRadius": @(cornerRadii.topLeft),
-        @"borderTopRightRadius": @(cornerRadii.topRight),
-        @"borderBottomLeftRadius": @(cornerRadii.bottomLeft),
-        @"borderBotomRightRadius": @(cornerRadii.bottomRight)
+        @"borderTopLeftRadius": @(cornerRadii.topLeftHorizontal),
+        @"borderTopRightRadius": @(cornerRadii.topRightHorizontal),
+        @"borderBottomLeftRadius": @(cornerRadii.bottomLeftHorizontal),
+        @"borderBotomRightRadius": @(cornerRadii.bottomRightHorizontal)
     }
   };
   self.onMeasureNode(eventData);
Copy link

github-actions bot commented Dec 4, 2024

Hey! Thanks for opening the issue. The issue doesn't seem to contain a link to a repro (a snack.expo.dev link or link to a GitHub repo under your username).

Can you provide a minimal repro which demonstrates the issue? A repro will help us debug the issue faster. Please try to keep the repro as small as possible and make sure that we can run it without additional setup.

@pep108
Copy link

pep108 commented Dec 9, 2024

react-native-shared-element+0.8.9.patch

Many thanks for providing a patch for this issue. Fixed my build problem and saved me time. Kudos!

@IjzerenHein
Copy link
Owner

Thank you @jparkrr for providing a patch for this 🙏
Will have look on incorporating this in a new release 👍

@sherikovic
Copy link

Build just errored out for the same reason. Thanks for the patch and looking forward to having it in a new release soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants