mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
iOS-specific LayoutAnimation integration
Summary: Turn on Fabric LayoutAnimations on iOS. I will gate this change behind a QE before landing. Changelog: [Internal] Reviewed By: shergin Differential Revision: D21583932 fbshipit-source-id: 0e0f988b44af37eb6fb22cccb48b0c7aa5020ca7
This commit is contained in:
committed by
Facebook GitHub Bot
parent
076ba4c920
commit
e781b31489
@@ -64,6 +64,12 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
- (facebook::react::MountingCoordinator::Shared)mountingCoordinatorWithSurfaceId:(facebook::react::SurfaceId)surfaceId;
|
||||
|
||||
- (void)onAnimationStarted;
|
||||
|
||||
- (void)onAllAnimationsComplete;
|
||||
|
||||
- (void)animationTick;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@@ -7,10 +7,12 @@
|
||||
|
||||
#import "RCTScheduler.h"
|
||||
|
||||
#import <react/animations/LayoutAnimationDriver.h>
|
||||
#import <react/componentregistry/ComponentDescriptorFactory.h>
|
||||
#import <react/debug/SystraceSection.h>
|
||||
#import <react/scheduler/Scheduler.h>
|
||||
#import <react/scheduler/SchedulerDelegate.h>
|
||||
#include <react/utils/RunLoopObserver.h>
|
||||
|
||||
#import <React/RCTFollyConvert.h>
|
||||
|
||||
@@ -61,23 +63,82 @@ class SchedulerDelegateProxy : public SchedulerDelegate {
|
||||
void *scheduler_;
|
||||
};
|
||||
|
||||
class LayoutAnimationDelegateProxy : public LayoutAnimationStatusDelegate, public RunLoopObserver::Delegate {
|
||||
public:
|
||||
LayoutAnimationDelegateProxy(void *scheduler) : scheduler_(scheduler) {}
|
||||
virtual ~LayoutAnimationDelegateProxy() {}
|
||||
|
||||
void onAnimationStarted() override
|
||||
{
|
||||
RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_;
|
||||
[scheduler onAnimationStarted];
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the LayoutAnimation engine completes all pending animations.
|
||||
*/
|
||||
void onAllAnimationsComplete() override
|
||||
{
|
||||
RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_;
|
||||
[scheduler onAllAnimationsComplete];
|
||||
}
|
||||
|
||||
void activityDidChange(RunLoopObserver::Delegate const *delegate, RunLoopObserver::Activity activity) const
|
||||
noexcept override
|
||||
{
|
||||
RCTScheduler *scheduler = (__bridge RCTScheduler *)scheduler_;
|
||||
[scheduler animationTick];
|
||||
}
|
||||
|
||||
private:
|
||||
void *scheduler_;
|
||||
};
|
||||
|
||||
@implementation RCTScheduler {
|
||||
std::shared_ptr<Scheduler> _scheduler;
|
||||
std::shared_ptr<LayoutAnimationDriver> _animationDriver;
|
||||
std::shared_ptr<SchedulerDelegateProxy> _delegateProxy;
|
||||
std::shared_ptr<LayoutAnimationDelegateProxy> _layoutAnimationDelegateProxy;
|
||||
RunLoopObserver::Unique _uiRunLoopObserver;
|
||||
BOOL _layoutAnimationsEnabled;
|
||||
}
|
||||
|
||||
- (instancetype)initWithToolbox:(facebook::react::SchedulerToolbox)toolbox
|
||||
{
|
||||
if (self = [super init]) {
|
||||
auto reactNativeConfig =
|
||||
toolbox.contextContainer->at<std::shared_ptr<const ReactNativeConfig>>("ReactNativeConfig");
|
||||
_layoutAnimationsEnabled = reactNativeConfig->getBool("react_fabric:enabled_layout_animations_ios");
|
||||
|
||||
_delegateProxy = std::make_shared<SchedulerDelegateProxy>((__bridge void *)self);
|
||||
_scheduler = std::make_shared<Scheduler>(toolbox, nullptr, _delegateProxy.get());
|
||||
|
||||
if (_layoutAnimationsEnabled) {
|
||||
_layoutAnimationDelegateProxy = std::make_shared<LayoutAnimationDelegateProxy>((__bridge void *)self);
|
||||
_animationDriver = std::make_unique<LayoutAnimationDriver>(_layoutAnimationDelegateProxy.get());
|
||||
_uiRunLoopObserver =
|
||||
toolbox.mainRunLoopObserverFactory(RunLoopObserver::Activity::BeforeWaiting, _layoutAnimationDelegateProxy);
|
||||
_uiRunLoopObserver->setDelegate(_layoutAnimationDelegateProxy.get());
|
||||
}
|
||||
|
||||
_scheduler = std::make_shared<Scheduler>(
|
||||
toolbox, (_animationDriver ? _animationDriver.get() : nullptr), _delegateProxy.get());
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)animationTick
|
||||
{
|
||||
_scheduler->animationTick();
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (_animationDriver) {
|
||||
_animationDriver->setLayoutAnimationStatusDelegate(nullptr);
|
||||
}
|
||||
_animationDriver = nullptr;
|
||||
|
||||
_scheduler->setDelegate(nullptr);
|
||||
}
|
||||
|
||||
@@ -90,7 +151,13 @@ class SchedulerDelegateProxy : public SchedulerDelegate {
|
||||
SystraceSection s("-[RCTScheduler startSurfaceWithSurfaceId:...]");
|
||||
|
||||
auto props = convertIdToFollyDynamic(initialProps);
|
||||
_scheduler->startSurface(surfaceId, RCTStringFromNSString(moduleName), props, layoutConstraints, layoutContext);
|
||||
_scheduler->startSurface(
|
||||
surfaceId,
|
||||
RCTStringFromNSString(moduleName),
|
||||
props,
|
||||
layoutConstraints,
|
||||
layoutContext,
|
||||
(_animationDriver ? _animationDriver.get() : nullptr));
|
||||
_scheduler->renderTemplateToSurface(
|
||||
surfaceId, props.getDefault("navigationConfig").getDefault("initialUITemplate", "").getString());
|
||||
}
|
||||
@@ -127,4 +194,18 @@ class SchedulerDelegateProxy : public SchedulerDelegate {
|
||||
return _scheduler->findMountingCoordinator(surfaceId);
|
||||
}
|
||||
|
||||
- (void)onAnimationStarted
|
||||
{
|
||||
if (_uiRunLoopObserver) {
|
||||
_uiRunLoopObserver->enable();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onAllAnimationsComplete
|
||||
{
|
||||
if (_uiRunLoopObserver) {
|
||||
_uiRunLoopObserver->disable();
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user