Add support for nested components in legacy interop
Summary: changelog: [internal] Reviewed By: ShikaSD Differential Revision: D34173837 fbshipit-source-id: 09fbf12e9d8eb13a170ff92afff97f203d0ef805
This commit is contained in:
Родитель
8bc324fd34
Коммит
5e88223d85
|
@ -15,3 +15,9 @@ RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollec
|
|||
*/
|
||||
RCT_EXTERN BOOL RCTExperimentGetPreemptiveViewAllocationDisabled(void);
|
||||
RCT_EXTERN void RCTExperimentSetPreemptiveViewAllocationDisabled(BOOL value);
|
||||
|
||||
/*
|
||||
* Interop layer keep view hierarchy.
|
||||
*/
|
||||
RCT_EXTERN BOOL RCTGetInteropLayerKeepViewHierarchy(void);
|
||||
RCT_EXTERN void RCTSetInteropLayerKeepViewHierarchy(BOOL value);
|
||||
|
|
|
@ -24,3 +24,18 @@ void RCTExperimentSetPreemptiveViewAllocationDisabled(BOOL value)
|
|||
{
|
||||
RCTExperimentPreemptiveViewAllocationDisabled = value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Preemptive View Allocation
|
||||
*/
|
||||
static BOOL RCTInteropLayerKeepViewHierarchy = NO;
|
||||
|
||||
BOOL RCTGetInteropLayerKeepViewHierarchy()
|
||||
{
|
||||
return RCTInteropLayerKeepViewHierarchy;
|
||||
}
|
||||
|
||||
void RCTSetInteropLayerKeepViewHierarchy(BOOL value)
|
||||
{
|
||||
RCTInteropLayerKeepViewHierarchy = value;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
+ (BOOL)isSupported:(NSString *)componentName;
|
||||
|
||||
+ (void)supportLegacyViewManagerWithName:(NSString *)componentName;
|
||||
+ (void)supportLegacyViewManagersWithPrefix:(NSString *)prefix;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#import "RCTLegacyViewManagerInteropComponentView.h"
|
||||
|
||||
#import <React/RCTAssert.h>
|
||||
#import <React/RCTConstants.h>
|
||||
#import <React/UIView+React.h>
|
||||
#import <react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropComponentDescriptor.h>
|
||||
#import <react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropViewProps.h>
|
||||
|
@ -24,6 +25,7 @@ static NSString *const kRCTLegacyInteropChildIndexKey = @"index";
|
|||
NSMutableArray<UIView *> *_viewsToBeUnmounted;
|
||||
RCTLegacyViewManagerInteropCoordinatorAdapter *_adapter;
|
||||
LegacyViewManagerInteropShadowNode::ConcreteState::Shared _state;
|
||||
BOOL _hasInvokedForwardingWarning;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
|
@ -33,6 +35,7 @@ static NSString *const kRCTLegacyInteropChildIndexKey = @"index";
|
|||
_props = defaultProps;
|
||||
_viewsToBeMounted = [NSMutableArray new];
|
||||
_viewsToBeUnmounted = [NSMutableArray new];
|
||||
_hasInvokedForwardingWarning = NO;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -49,37 +52,7 @@ static NSString *const kRCTLegacyInteropChildIndexKey = @"index";
|
|||
return result;
|
||||
}
|
||||
|
||||
+ (NSMutableSet<NSString *> *)supportedViewManagers
|
||||
{
|
||||
static NSMutableSet<NSString *> *supported = [NSMutableSet setWithObjects:@"DatePicker",
|
||||
@"ProgressView",
|
||||
@"SegmentedControl",
|
||||
@"MaskedView",
|
||||
@"ARTSurfaceView",
|
||||
@"ARTText",
|
||||
@"ARTShape",
|
||||
@"ARTGroup",
|
||||
nil];
|
||||
return supported;
|
||||
}
|
||||
|
||||
+ (BOOL)isSupported:(NSString *)componentName
|
||||
{
|
||||
RCTLogNotAllowedForNewArchitecture(
|
||||
self,
|
||||
[NSString
|
||||
stringWithFormat:
|
||||
@"Legacy ViewManagers should be migrated to Fabric ComponentViews in the new architecture to reduce risk. Component using interop layer: %@",
|
||||
componentName]);
|
||||
return [[RCTLegacyViewManagerInteropComponentView supportedViewManagers] containsObject:componentName];
|
||||
}
|
||||
|
||||
+ (void)supportLegacyViewManagerWithName:(NSString *)componentName
|
||||
{
|
||||
[[RCTLegacyViewManagerInteropComponentView supportedViewManagers] addObject:componentName];
|
||||
}
|
||||
|
||||
- (RCTLegacyViewManagerInteropCoordinator *)coordinator
|
||||
- (RCTLegacyViewManagerInteropCoordinator *)_coordinator
|
||||
{
|
||||
if (_state != nullptr) {
|
||||
const auto &state = _state->getData();
|
||||
|
@ -96,6 +69,80 @@ static NSString *const kRCTLegacyInteropChildIndexKey = @"index";
|
|||
return coordinator.componentViewName;
|
||||
}
|
||||
|
||||
#pragma mark - Method forwarding
|
||||
|
||||
- (void)forwardInvocation:(NSInvocation *)anInvocation
|
||||
{
|
||||
if (!_hasInvokedForwardingWarning) {
|
||||
_hasInvokedForwardingWarning = YES;
|
||||
NSLog(
|
||||
@"Invoked unsupported method on RCTLegacyViewManagerInteropComponentView. Resulting to noop instead of a crash.");
|
||||
}
|
||||
}
|
||||
|
||||
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
|
||||
{
|
||||
return [super methodSignatureForSelector:aSelector] ?: [self.contentView methodSignatureForSelector:aSelector];
|
||||
}
|
||||
|
||||
#pragma mark - Supported ViewManagers
|
||||
|
||||
+ (NSMutableSet<NSString *> *)supportedViewManagers
|
||||
{
|
||||
static NSMutableSet<NSString *> *supported = [NSMutableSet setWithObjects:@"DatePicker",
|
||||
@"ProgressView",
|
||||
@"SegmentedControl",
|
||||
@"MaskedView",
|
||||
@"ARTSurfaceView",
|
||||
@"ARTText",
|
||||
@"ARTShape",
|
||||
@"ARTGroup",
|
||||
nil];
|
||||
return supported;
|
||||
}
|
||||
|
||||
+ (NSMutableSet<NSString *> *)supportedViewManagersPrefixes
|
||||
{
|
||||
static NSMutableSet<NSString *> *supported = [NSMutableSet new];
|
||||
return supported;
|
||||
}
|
||||
|
||||
+ (BOOL)isSupported:(NSString *)componentName
|
||||
{
|
||||
RCTLogNotAllowedForNewArchitecture(
|
||||
self,
|
||||
[NSString
|
||||
stringWithFormat:
|
||||
@"Legacy ViewManagers should be migrated to Fabric ComponentViews in the new architecture to reduce risk. Component using interop layer: %@",
|
||||
componentName]);
|
||||
|
||||
// Step 1: check if ViewManager with specified name is supported.
|
||||
BOOL isComponentNameSupported =
|
||||
[[RCTLegacyViewManagerInteropComponentView supportedViewManagers] containsObject:componentName];
|
||||
if (isComponentNameSupported) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Step 2: check if component has supported prefix.
|
||||
for (NSString *item in [RCTLegacyViewManagerInteropComponentView supportedViewManagersPrefixes]) {
|
||||
if ([componentName hasPrefix:item]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
+ (void)supportLegacyViewManagersWithPrefix:(NSString *)prefix
|
||||
{
|
||||
[[RCTLegacyViewManagerInteropComponentView supportedViewManagersPrefixes] addObject:prefix];
|
||||
}
|
||||
|
||||
+ (void)supportLegacyViewManagerWithName:(NSString *)componentName
|
||||
{
|
||||
[[RCTLegacyViewManagerInteropComponentView supportedViewManagers] addObject:componentName];
|
||||
}
|
||||
|
||||
#pragma mark - RCTComponentViewProtocol
|
||||
|
||||
- (void)prepareForRecycle
|
||||
|
@ -105,6 +152,7 @@ static NSString *const kRCTLegacyInteropChildIndexKey = @"index";
|
|||
[_viewsToBeUnmounted removeAllObjects];
|
||||
_state.reset();
|
||||
self.contentView = nil;
|
||||
_hasInvokedForwardingWarning = NO;
|
||||
[super prepareForRecycle];
|
||||
}
|
||||
|
||||
|
@ -140,7 +188,7 @@ static NSString *const kRCTLegacyInteropChildIndexKey = @"index";
|
|||
[super finalizeUpdates:updateMask];
|
||||
|
||||
if (!_adapter) {
|
||||
_adapter = [[RCTLegacyViewManagerInteropCoordinatorAdapter alloc] initWithCoordinator:self.coordinator
|
||||
_adapter = [[RCTLegacyViewManagerInteropCoordinatorAdapter alloc] initWithCoordinator:[self _coordinator]
|
||||
reactTag:self.tag];
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
_adapter.eventInterceptor = ^(std::string eventName, folly::dynamic event) {
|
||||
|
@ -157,7 +205,16 @@ static NSString *const kRCTLegacyInteropChildIndexKey = @"index";
|
|||
for (NSDictionary *mountInstruction in _viewsToBeMounted) {
|
||||
NSNumber *index = mountInstruction[kRCTLegacyInteropChildIndexKey];
|
||||
UIView *childView = mountInstruction[kRCTLegacyInteropChildComponentKey];
|
||||
[_adapter.paperView insertReactSubview:childView atIndex:index.integerValue];
|
||||
if (RCTGetInteropLayerKeepViewHierarchy()) {
|
||||
if ([childView isKindOfClass:[RCTLegacyViewManagerInteropComponentView class]]) {
|
||||
UIView *target = ((RCTLegacyViewManagerInteropComponentView *)childView).contentView;
|
||||
[_adapter.paperView insertReactSubview:target atIndex:index.integerValue];
|
||||
} else {
|
||||
[_adapter.paperView insertReactSubview:childView atIndex:index.integerValue];
|
||||
}
|
||||
} else {
|
||||
[_adapter.paperView insertReactSubview:childView atIndex:index.integerValue];
|
||||
}
|
||||
}
|
||||
|
||||
[_viewsToBeMounted removeAllObjects];
|
||||
|
|
|
@ -263,6 +263,10 @@ static BackgroundExecutor RCTGetBackgroundExecutor()
|
|||
RCTExperimentSetPreemptiveViewAllocationDisabled(YES);
|
||||
}
|
||||
|
||||
RCTSetInteropLayerKeepViewHierarchy(
|
||||
reactNativeConfig &&
|
||||
reactNativeConfig->getBool("react_native_new_architecture:interop_layer_keep_view_hierarchy"));
|
||||
|
||||
auto componentRegistryFactory =
|
||||
[factory = wrapManagedObject(_mountingManager.componentViewRegistry.componentViewFactory)](
|
||||
EventDispatcher::Weak const &eventDispatcher, ContextContainer::Shared const &contextContainer) {
|
||||
|
|
|
@ -43,6 +43,11 @@ static std::string moduleNameFromComponentName(const std::string &componentName)
|
|||
return componentName + "Manager";
|
||||
}
|
||||
|
||||
std::string rnPrefix("RN");
|
||||
if (std::mismatch(rnPrefix.begin(), rnPrefix.end(), componentName.begin()).first == rnPrefix.end()) {
|
||||
return componentName + "Manager";
|
||||
}
|
||||
|
||||
return "RCT" + componentName + "Manager";
|
||||
}
|
||||
|
||||
|
|
|
@ -86,8 +86,10 @@ using namespace facebook::react;
|
|||
|
||||
- (void)setProps:(folly::dynamic const &)props forView:(UIView *)view
|
||||
{
|
||||
NSDictionary<NSString *, id> *convertedProps = convertFollyDynamicToId(props);
|
||||
[_componentData setProps:convertedProps forView:view];
|
||||
if (props.isObject()) {
|
||||
NSDictionary<NSString *, id> *convertedProps = convertFollyDynamicToId(props);
|
||||
[_componentData setProps:convertedProps forView:view];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)componentViewName
|
||||
|
|
Загрузка…
Ссылка в новой задаче