Skip to content

Commit

Permalink
remove animation from borderLayer to stop unwanted animations
Browse files Browse the repository at this point in the history
Summary:
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
  • Loading branch information
sammy-SC authored and facebook-github-bot committed Feb 8, 2024
1 parent f6b984d commit 771b47a
Showing 1 changed file with 13 additions and 13 deletions.
Original file line number Diff line number Diff line change
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 @@ -404,9 +404,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 @@ -610,10 +608,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 @@ -626,11 +621,12 @@ - (void)invalidateLayer
layer.backgroundColor = backgroundColor;
} 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 @@ -671,6 +667,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 771b47a

Please sign in to comment.