Skip to content

Commit 41c788a

Browse files
sammy-SCfacebook-github-bot
authored andcommitted
Make sure opacity and transform are applied in native animation
Summary: Changelog: [internal] Problem: `props.transform` gets out of sync with `self.layer.transform`. To avoid writing out value of transform matrix, in the follow example I will only consider identity matrix and non-identity matrix. It is sufficient to demonstrate the point. 1. View is reused with transform being something besides identity. This causes `props.transform` and `self.layer.transform` to be non-identity. 2. View is taken from pool and animated with transform set to non-identity. 3. React JS props arrive and set `view.props` to identity but `self.layer.transform` stays unchanged because it is managed by native animation. This is the point where `props.transform` and `self.layer.transform` get out of sync. 4. Native animation wants to set transform to identity to finish the animation. But inside `[RCTViewComponentView updateProps:oldProps:]` `self.layer.transform` does not get set because current `view.props` is already identity. Solution: After native animation layer calls `[RCTViewComponentView updateProps:oldProps:]`, verify that values were set. If they weren't, set them directly without depending on `[RCTViewComponentView updateProps:oldProps:]`. Reviewed By: JoshuaGross Differential Revision: D24538442 fbshipit-source-id: ba8c59c5c9bb751306118bd1c7f0ccd9d0fb7fba
1 parent 4b58038 commit 41c788a

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

React/Fabric/Mounting/RCTMountingManager.mm

+14
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#import <React/RCTAssert.h>
1313
#import <React/RCTFollyConvert.h>
14+
#import <React/RCTLog.h>
1415
#import <React/RCTUtils.h>
1516
#import <react/renderer/core/LayoutableShadowNode.h>
1617
#import <react/renderer/core/RawProps.h>
@@ -228,6 +229,19 @@ - (void)synchronouslyUpdateViewOnUIThread:(ReactTag)reactTag
228229
componentView.propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN = nil;
229230
[componentView updateProps:newProps oldProps:oldProps];
230231
componentView.propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN = propKeys;
232+
233+
const auto &newViewProps = *std::static_pointer_cast<const ViewProps>(newProps);
234+
235+
if (props[@"transform"] &&
236+
!CATransform3DEqualToTransform(
237+
RCTCATransform3DFromTransformMatrix(newViewProps.transform), componentView.layer.transform)) {
238+
RCTLogWarn(@"transform was not applied during [RCTViewComponentView updateProps:oldProps:]");
239+
componentView.layer.transform = RCTCATransform3DFromTransformMatrix(newViewProps.transform);
240+
}
241+
if (props[@"opacity"] && componentView.layer.opacity != (float)newViewProps.opacity) {
242+
RCTLogWarn(@"opacity was not applied during [RCTViewComponentView updateProps:oldProps:]");
243+
componentView.layer.opacity = newViewProps.opacity;
244+
}
231245
}
232246

233247
- (void)synchronouslyDispatchCommandOnUIThread:(ReactTag)reactTag

0 commit comments

Comments
 (0)