hi, this code shows different result on android and iOS:
export default class TestClip extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.child}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
width: 100,
height: 100,
backgroundColor: 'red',
},
child: {
position: 'absolute',
width: 100,
height: 100,
top: 50,
left: 50,
backgroundColor: 'green',
},
});

I think this is caused by:
on android ViewGroup's clipChildren is true by default,
on iOS UIView's clipToBounds is NO by default.
Tested adding setClipChildren(true) to the base class ReactViewGroup on android can solve this, but not sure if this can cause performance issue. maybe exporting clipChildren as a property on both platform is better?
Isn't this what https://facebook.github.io/react-native/docs/view.html#removeclippedsubviews is for?
@hey99xx it's not the same thing I think,
removeClippedSubviews controls wether clipped subviews should be removed from view hierarchy.
clipChildren or clipToBounds controls wether subviews should be drawn outside of parent's bounds.
@littlesome I think this is probably explaining the issue https://facebook.github.io/react-native/releases/0.26/docs/known-issues.html#the-overflow-style-property-defaults-to-hidden-and-cannot-be-changed-on-android
Ok this has been fixed in master: https://github.com/facebook/react-native/commit/625c8cb83c7be01b1d5f646b70f8fb1d4c70a45c
Can you try the RN code on master and see if the fix works for you?
@ericvicenti That commit seems to be only iOS, however @anttimo 's link says "This is only on Android; it works as expected on iOS." so I think the expected fix will be an Android one. Or if this commit just addresses the clip implementation difference in @littlesome 's question, maybe he has an answer now.
@ericvicenti thanks for the response, I will try this later, not got a computer by hand now. And @hey99xx I agree this is an android issue, and not sure if this has something to do with RN's clipping implementation, i will go deeper into the source later, thanks:)
Tested adding setClipChildren(true) to the base class ReactViewGroup on android can solve this
Can someone chime on on why this isn't the solution?
edit: @littlesome I think you meant to write setClipChildren(false) in your original post.
I'm a fan of making this behavior consistent between ios and android
In case there are others following this discussion, after investigating this a bit on my own, I've decided to put setClipChildren(false) as the default for Android on the ReactViewGroup internally.
puts on graphics engineer hat
Clipping children is distinct from removeClippedSubviews. Personally, I think removeClippedSubviews isn't a great name (cullOccludedSubviews is probably better). The function of removeClippedSubviews is to remove occluded nodes from the tree completely. This is done through bounding box computations as in @ericvicenti 's commit. This saves JS execution time because you now remove from the render tree potentially many nodes which would have otherwise needed JS computation in order to resolve state + props and determine if they should rerender or not (in addition to all their children). The behavior of setClipChildren however does none of that. Regardless of whether the element is being clipped or not, it must belong to the render tree and so no savings are to be had on the JS thread (it has already failed the bounding box test). Furthermore, the UI thread needs to issue a draw call for it regardless of how much of it is being clipped. Even if only one pixel is shown, you need the draw call. So at least as far as the CPU is concerned, there is no optimization to be had here. The place where we are potentially dropping frames is the GPU (which on phones is a shared resource with the CPU) due to potential overdraw or because the thing we are drawing is expensive to fill. Most people building React Native applications are doing absolutely nothing that would affect fill rate (aka the time it takes to draw each pixel * the number of pixels * the overdraw factor). Even a simple image or video isn't super expensive (compare to a game where each pixel may need to sample multiple textures, perform a lighting computation, sample the shadow buffer, etc).
In short, I think the additional cost for having this setting is negligible given the resources that are actually constrained (most often the JS thread) and this setting should just be on by default. I've turned it on here and would like to hear from the RN team if possible if there are any wonky unforeseen consequences for doing so, which would probably surprise me, but then I'd learn something about the engine.
First, I now understood that clipToBounds and removeClippedSubviews are not the same. I'm not sure whether the only benefit is to the GPU, or to the CPU as well; because I have seen huge improvements in memory usage in my app. Also on Android (and probably on iOS as well), there are view callbacks to notify that they're no longer attached to any window, so they can drop resources, not sure if this affects at all.
That said, I prefer not to diverge the conversation further, since it's clear OP's issue is not about clipping subviews but about bounds. If setClipChildren(boolean) is an acceptable fix, I would be a fan of it being a native backed prop on <View> components. However, we could come up with a better name than clipChildren={false} otherwise it'll often be confused with removeClippedSubviews.
Same issue here.. would be nice to have a solution without modifying the Core of RN
Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!
If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:
If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.
Hi, is there any solution to this? I'm still having issues up to this day. IOS is working as expected, but on android it's get clipped.
@littlesome have you able to fix this issue?
anyone has workaround or solution for this?
I am still having this issue...
+1, same issue
Please open a new issue and make sure it follows the template.
Most helpful comment
Hi, is there any solution to this? I'm still having issues up to this day. IOS is working as expected, but on android it's get clipped.