Skip to content

Commit

Permalink
[fabric] Fix View content clipping to bounds toggling randomly on mount
Browse files Browse the repository at this point in the history
Summary:
React View components take the assumption that content clipping to the view's bounds is disabled by default.

This diff fixes the propagation of the clipping setting to the `RCTUIView` instance and the backing core animation layer, by keeping both settings in sync with the component props.

Core Animation on macOS also enabled clipping when a corner radius (border radius) is set on the layer. This would result in the random toggling of the clipping (overflow style) on the native view and make it out of sync with the component properties.

This is being fixed by restoring the current `clipsToBounds` setting after setting the layer's corner radius property.

Test Plan:
- Run Cosmo Studio
- Open the UI Reference (Developer > Show UI Reference)
- Open the 'Inputs' example
- Switch between other examples and back to 'Inputs' to verify that the clipping stays unchanged.

| Before | After |
|--|
|  https://pxl.cl/4xDWc  |  https://pxl.cl/4xDWt  |

Reviewers: shawndempsey, bedeoverend, #rn-desktop, #cosmo

Reviewed By: bedeoverend

Subscribers: generatedunixname499725568

Differential Revision: https://phabricator.intern.facebook.com/D55213691

Tasks: T182033885

Tags: uikit-diff

# Conflicts:
#	packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm
  • Loading branch information
Nick Lefever authored and shwanton committed May 2, 2024
1 parent 460ac95 commit 409de4c
Showing 1 changed file with 24 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ - (instancetype)initWithFrame:(CGRect)frame
_reactSubviews = [NSMutableArray new];
#if !TARGET_OS_OSX // [macOS]
self.multipleTouchEnabled = YES;
#endif // [macOS]
#else // [macOS
// React views have their bounds clipping disabled by default
self.clipsToBounds = NO;
#endif // macOS]
}
return self;
}
Expand Down Expand Up @@ -762,6 +765,17 @@ static RCTBorderStyle RCTBorderStyleFromBorderStyle(BorderStyle borderStyle)
}
#endif // macOS]

#if TARGET_OS_OSX // [macOS
- (void)setClipsToBounds:(BOOL)clipsToBounds
{
// Set the property managed by RCTUIView
super.clipsToBounds = clipsToBounds;

// Bounds clipping must also be configured on the view's layer
self.layer.masksToBounds = clipsToBounds;
}
#endif // macOS]

- (void)invalidateLayer
{
CALayer *layer = self.layer;
Expand Down Expand Up @@ -845,8 +859,17 @@ - (void)invalidateLayer
CGColorRef borderColor = RCTCreateCGColorRefFromSharedColor(borderMetrics.borderColors.left);
layer.borderColor = borderColor;
CGColorRelease(borderColor);
#if TARGET_OS_OSX // [macOS]
layer.cornerRadius = (CGFloat)borderMetrics.borderRadii.topLeft;

#else // [macOS
// Setting the corner radius on view's layer enables back clipping to bounds. To
// avoid getting the native view out of sync with the component's props, we make
// sure that clipsToBounds stays unchanged after setting the corner radius.
BOOL clipsToBounds = self.clipsToBounds;
layer.cornerRadius = (CGFloat)borderMetrics.borderRadii.topLeft;
self.clipsToBounds = clipsToBounds;
#endif // macOS]
layer.cornerCurve = CornerCurveFromBorderCurve(borderMetrics.borderCurves.topLeft);

layer.backgroundColor = _backgroundColor.CGColor;
Expand Down

0 comments on commit 409de4c

Please sign in to comment.