IjzerenHein / IjzerenHein/react-native-shared-element
Incompatible with react-native 0.76 on iOS due to border radii
- Dominant language
- TypeScript
- Stars
- 2.3k
- Forks
- 113
- PR merge metrics
- No merged PRs in 30d
Description
There were some changes to RCTCornerRadii in 0.76: https://github.com/facebook/react-native/pull/46009. This causes this package to error during compilation for iOS.
I made a quick patch with [patch-package](https://www.npmjs.com/package/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`:
```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);
```
Contributor guide
No contributing guide indexed for this repository
Research direction
Start by comparing the React Native 0.76 RCTCornerRadii changes with ios/RNSharedElementCornerRadii.m, ios/RNSharedElementStyle.m, and ios/RNSharedElementTransition.m. Verify the iOS package compiles against React Native 0.76 and that the resulting handling covers asymmetric radii without breaking supported versions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- objective-c, react-native
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100