Skip to content

Commit

Permalink
remove animation from borderLayer to stop unwanted animations (#42922)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #42922

changelog: [fix][ios] prevent unwanted border animation

The problem: CALayer and its properties are animatable. If RN applies mutations inside an animation block, it will animate. In this particular example, it was animated because of a transition applied by the library and because we were not creating new views, but recycling views from previous screen.

This caused size of _borderLayer to change from value A to value B inside of animation block. To resolve this, call removeAllAnimations on borderLayer.

Reviewed By: cipolleschi

Differential Revision: D53566886

fbshipit-source-id: 98e0b01a9185046e1ee500665c1832060ecc8884
  • Loading branch information
sammy-SC authored and hurali97 committed Mar 6, 2024
1 parent 02f163e commit d979491
Showing 1 changed file with 13 additions and 13 deletions.
Expand Up @@ -28,7 +28,7 @@

@implementation RCTViewComponentView {
UIColor *_backgroundColor;
CALayer *_borderLayer;
__weak CALayer *_borderLayer;
BOOL _needsInvalidateLayer;
BOOL _isJSResponder;
BOOL _removeClippedSubviews;
Expand Down Expand Up @@ -397,9 +397,7 @@ - (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
_layoutMetrics = layoutMetrics;
_needsInvalidateLayer = YES;

if (_borderLayer) {
_borderLayer.frame = self.layer.bounds;
}
_borderLayer.frame = self.layer.bounds;

if (_contentView) {
_contentView.frame = RCTCGRectFromRect(_layoutMetrics.getContentFrame());
Expand Down Expand Up @@ -601,10 +599,7 @@ - (void)invalidateLayer

if (useCoreAnimationBorderRendering) {
layer.mask = nil;
if (_borderLayer) {
[_borderLayer removeFromSuperlayer];
_borderLayer = nil;
}
[_borderLayer removeFromSuperlayer];

layer.borderWidth = (CGFloat)borderMetrics.borderWidths.left;
CGColorRef borderColor = RCTCreateCGColorRefFromSharedColor(borderMetrics.borderColors.left);
Expand All @@ -617,11 +612,12 @@ - (void)invalidateLayer
layer.backgroundColor = _backgroundColor.CGColor;
} else {
if (!_borderLayer) {
_borderLayer = [CALayer new];
_borderLayer.zPosition = -1024.0f;
_borderLayer.frame = layer.bounds;
_borderLayer.magnificationFilter = kCAFilterNearest;
[layer addSublayer:_borderLayer];
CALayer *borderLayer = [CALayer new];
borderLayer.zPosition = -1024.0f;
borderLayer.frame = layer.bounds;
borderLayer.magnificationFilter = kCAFilterNearest;
[layer addSublayer:borderLayer];
_borderLayer = borderLayer;
}

layer.backgroundColor = nil;
Expand Down Expand Up @@ -662,6 +658,10 @@ - (void)invalidateLayer
}
}

// If mutations are applied inside of Animation block, it may cause _borderLayer to be animated.
// To stop that, imperatively remove all animations from _borderLayer.
[_borderLayer removeAllAnimations];

// Stage 2.5. Custom Clipping Mask
CAShapeLayer *maskLayer = nil;
CGFloat cornerRadius = 0;
Expand Down

0 comments on commit d979491

Please sign in to comment.