A framework for building native applications using React
fix(iOS): `boxShadow + overflow hidden` combination affecting pointer event `box-none` and scale transform. (#52413)
Summary:
This issue is only reproducible with combination of `overflow: hidden` and `boxShadow` i.e. when a [container view](https://github.com/facebook/react-native/blob/2ce7eab5f998788ffa8346b63cc4901d026456ba/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm#L799) is added to the hierarchy.
### Case 1:
```jsx
<Pressable
pointerEvents="box-none"
style={{ width: 300, height: 300, boxShadow: "0 0 100px 0 rgba(0, 0, 0, 0.5)", overflow: "hidden" }}
onPress={() => {
alert("Tapped");
}}
/>
```
Here the view has `box-none` but it will still trigger the press event because this [line](https://github.com/facebook/react-native/blob/2ce7eab5f998788ffa8346b63cc4901d026456ba/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm#L658) returns the `_containerView` as `hitView` and this condition gets [fullfilled](https://github.com/facebook/react-native/blob/2ce7eab5f998788ffa8346b63cc4901d026456ba/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm#L676) (since it is not self). To fix this issue we should iterate on `self.currentContainerView.subviews`.
### Case 2:
Transform scale clipping child view.
```jsx
<Pressable
pointerEvents="box-none"
style={{ width: 300, height: 300, overflow: "hidden",
transform: [
{ scale: 0.5 },
],
boxShadow: "0 0 100px 0 rgba(0, 0, 0, 0.5)",
}}
onPress={() => {
alert("parent view");
}}
>
<Pressable
style={{
position: "absolute",
bottom: 0,
right: 0,
backgroundColor: "blue",
height: 50,
width: 100,
}}
onPress={() => {
alert("child view");
}}
>
<Text>Press me</Text>
</Pressable>
</Pressable>;
```
The above style hides the child view on iOS whereas it is visible on android.
| iOS | Android |
|---|---|
| <img src="https://github.com/user-attachments/assets/14713ec9-1ae7-4425-9348-946d507188e8" width="200px" /> | <img src="https://github.com/user-attachments/assets/0f6e2368-037d-4b03-8a85-8a08f1578ff6" width="200px" /> |
This happens because `containerView` uses `self.frame` property which gets mutated due to scale transform. So containerView becomes `actualSize * scale * scale` instead of `actualSize * scale` and ends up clipping child views because of overflow hidden. Please checkout the layout hierarchy in the below screenshot. To fix it we need to use `self.bounds` instead of `self.frame` when setting the frame for container.
<img src="https://github.com/user-attachments/assets/9ce41756-f41f-4782-bfc9-b0c281f314b7" width="300px" />
## Changelog:
[IOS] [FIXED] - boxShadow + overflow hidden combination interfering with pointerEvents and transform scale.
<!-- Help reviewers and the release process by writing your own changelog entry.
Pick one each for the category and type tags:
For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
Pull Request resolved: https://github.com/facebook/react-native/pull/52413
Test Plan:
Test above example snippets and pointer events examples in RNTester.
cc - joevilches
Reviewed By: cortinico, jorge-cab
Differential Revision: D77872110
Pulled By: joevilches
fbshipit-source-id: e9693c79b47379531510607921ffaa6d6cc5c17b N
nishan (o^▽^o) committed
c8e5f9766b8caaf66aa61ef48eeab740a10a725a
Parent: 1c5e0ff
Committed by Facebook GitHub Bot <facebook-github-bot@users.noreply.github.com>
on 9/18/2025, 9:06:00 PM