mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Prevent Fabric from changing props if they are managed by Animated
Summary: Changelog: [internal] # Problem Fabric doesn't know when NativeAnimatedModule control a prop and overrides its change whenever any prop changes. For example component A is animating its opacity from 1 to 0. NativeAnimatedModule starts calling `[RCTViewComponentView updateProps:oldProps:]` method interpolating opacity from 1 to 0. After it is finished, if any prop is updated on the component. Its opacity will be set to default. # Fix This is a temporary problem until Unified Animation System is put in place. To work around the issue for now, we keep a set of prop keys controlled by animated and only update the prop if it isn't in this list. List is cleared when the component is reused. Reviewed By: JoshuaGross Differential Revision: D24046848 fbshipit-source-id: 63cca6854f97b2de764cb3ed505d328323c64525
This commit is contained in:
committed by
Facebook GitHub Bot
parent
61cfa97067
commit
b2c022ec54
@@ -23,6 +23,7 @@ using namespace facebook::react;
|
||||
UIColor *_backgroundColor;
|
||||
CALayer *_borderLayer;
|
||||
BOOL _needsInvalidateLayer;
|
||||
NSSet<NSString *> *_propKeysManagedByAnimated;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
@@ -83,6 +84,11 @@ using namespace facebook::react;
|
||||
return concreteComponentDescriptorProvider<ViewComponentDescriptor>();
|
||||
}
|
||||
|
||||
- (void)setPropKeysManagedByAnimated:(nullable NSSet<NSString *> *)propKeys
|
||||
{
|
||||
_propKeysManagedByAnimated = propKeys;
|
||||
}
|
||||
|
||||
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
|
||||
{
|
||||
#ifndef NS_BLOCK_ASSERTIONS
|
||||
@@ -102,7 +108,7 @@ using namespace facebook::react;
|
||||
BOOL needsInvalidateLayer = NO;
|
||||
|
||||
// `opacity`
|
||||
if (oldViewProps.opacity != newViewProps.opacity) {
|
||||
if (oldViewProps.opacity != newViewProps.opacity && ![_propKeysManagedByAnimated containsObject:@"opacity"]) {
|
||||
self.layer.opacity = (CGFloat)newViewProps.opacity;
|
||||
needsInvalidateLayer = YES;
|
||||
}
|
||||
@@ -161,7 +167,7 @@ using namespace facebook::react;
|
||||
}
|
||||
|
||||
// `transform`
|
||||
if (oldViewProps.transform != newViewProps.transform) {
|
||||
if (oldViewProps.transform != newViewProps.transform && ![_propKeysManagedByAnimated containsObject:@"transform"]) {
|
||||
self.layer.transform = RCTCATransform3DFromTransformMatrix(newViewProps.transform);
|
||||
self.layer.allowsEdgeAntialiasing = newViewProps.transform != Transform::Identity();
|
||||
}
|
||||
@@ -286,6 +292,17 @@ using namespace facebook::react;
|
||||
- (void)prepareForRecycle
|
||||
{
|
||||
[super prepareForRecycle];
|
||||
|
||||
// If view was managed by animated, its props need to align with UIView's properties.
|
||||
auto const &props = *std::static_pointer_cast<ViewProps const>(_props);
|
||||
if ([_propKeysManagedByAnimated containsObject:@"transform"]) {
|
||||
self.layer.transform = RCTCATransform3DFromTransformMatrix(props.transform);
|
||||
}
|
||||
if ([_propKeysManagedByAnimated containsObject:@"opacity"]) {
|
||||
self.layer.opacity = (CGFloat)props.opacity;
|
||||
}
|
||||
|
||||
_propKeysManagedByAnimated = nil;
|
||||
_eventEmitter.reset();
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,8 @@ typedef NS_OPTIONS(NSInteger, RNComponentViewUpdateMask) {
|
||||
*/
|
||||
- (facebook::react::SharedProps)props;
|
||||
|
||||
- (void)setPropKeysManagedByAnimated:(nullable NSSet<NSString *> *)propKeys;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -222,7 +222,9 @@ static void RCTPerformMountInstructions(
|
||||
UIView<RCTComponentViewProtocol> *componentView = [_componentViewRegistry findComponentViewWithTag:reactTag];
|
||||
SharedProps oldProps = [componentView props];
|
||||
SharedProps newProps = componentDescriptor.cloneProps(oldProps, RawProps(convertIdToFollyDynamic(props)));
|
||||
[componentView setPropKeysManagedByAnimated:nil];
|
||||
[componentView updateProps:newProps oldProps:oldProps];
|
||||
[componentView setPropKeysManagedByAnimated:[NSSet setWithArray:props.allKeys]];
|
||||
}
|
||||
|
||||
- (void)synchronouslyDispatchCommandOnUIThread:(ReactTag)reactTag
|
||||
|
||||
@@ -39,6 +39,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
- (facebook::react::SharedProps)props;
|
||||
|
||||
- (void)setPropKeysManagedByAnimated:(nullable NSSet<NSString *> *)propKeys;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -132,4 +132,9 @@ using namespace facebook::react;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
- (void)setPropKeysManagedByAnimated:(nullable NSSet<NSString *> *)propKeys
|
||||
{
|
||||
// Default implementation does nothing.
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user