From 6f2121ab9dc81ebebaa4991946596be54bac2f62 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 7 Apr 2022 09:44:44 +0200 Subject: [PATCH 001/156] chore: Set RN_FABRIC_ENABLED compiler flag when fabric is enabled --- RNScreens.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RNScreens.podspec b/RNScreens.podspec index ab37cb9404..b224c31341 100644 --- a/RNScreens.podspec +++ b/RNScreens.podspec @@ -29,7 +29,7 @@ Pod::Spec.new do |s| "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", } s.platforms = { ios: '11.0', tvos: '11.0' } - s.compiler_flags = folly_compiler_flags + s.compiler_flags = folly_compiler_flags + '-DRN_FABRIC_ENABLED' s.source_files = 'ios/**/*.{h,m,mm,cpp}' s.requires_arc = true From 00fc6db94ce964fd754594f267de2875a69e6bfa Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 8 Apr 2022 14:59:51 +0200 Subject: [PATCH 002/156] refract: Move RNSScreenComponentView implementation to RNSScreenView && RNSScreenController to RNSScreen --- ios/RNSScreen.h | 79 +++-- ios/{RNSScreen.m => RNSScreen.mm} | 501 ++++++++++++++++++++++++++++-- ios/RNSScreenComponentView.h | 57 ---- ios/RNSScreenComponentView.mm | 485 ----------------------------- ios/RNSScreenController.h | 12 - ios/RNSScreenController.mm | 198 ------------ 6 files changed, 541 insertions(+), 791 deletions(-) rename ios/{RNSScreen.m => RNSScreen.mm} (65%) delete mode 100644 ios/RNSScreenComponentView.h delete mode 100644 ios/RNSScreenComponentView.mm delete mode 100644 ios/RNSScreenController.h delete mode 100644 ios/RNSScreenController.mm diff --git a/ios/RNSScreen.h b/ios/RNSScreen.h index a3a07075df..4c59f9a334 100644 --- a/ios/RNSScreen.h +++ b/ios/RNSScreen.h @@ -1,10 +1,15 @@ #import -#import #import #import "RNSEnums.h" #import "RNSScreenContainer.h" +#if RN_FABRIC_ENABLED +#import +#else +#import +#endif + @interface RCTConvert (RNSScreen) + (RNSScreenStackPresentation)RNSScreenStackPresentation:(id)json; @@ -12,6 +17,7 @@ #if !TARGET_OS_TV + (RNSStatusBarStyle)RNSStatusBarStyle:(id)json; ++ (UIStatusBarAnimation)UIStatusBarAnimation:(id)json; + (UIInterfaceOrientationMask)UIInterfaceOrientationMask:(id)json; #endif @@ -20,8 +26,13 @@ @interface RNSScreen : UIViewController - (instancetype)initWithView:(UIView *)view; -- (void)notifyFinishTransitioning; - (UIViewController *)findChildVCForConfigAndTrait:(RNSWindowTrait)trait includingModals:(BOOL)includingModals; +#ifdef RN_FABRIC_ENABLED +- (void)setViewToSnapshot:(UIView *)snapshot; +- (void)resetViewToScreen; +#else +- (void)notifyFinishTransitioning; +#endif @end @@ -29,8 +40,39 @@ @end -@interface RNSScreenView : RCTView +#ifdef RN_FABRIC_ENABLED +#define BASE_VIEW RCTViewComponentView +#else +#define BASE_VIEW RCTView +#endif + +@interface RNSScreenView : BASE_VIEW + +@property (nonatomic) BOOL fullScreenSwipeEnabled; +@property (nonatomic) BOOL gestureEnabled; +@property (nonatomic) BOOL hasStatusBarHiddenSet; +@property (nonatomic) BOOL hasStatusBarStyleSet; +@property (nonatomic) BOOL hasStatusBarAnimationSet; +@property (nonatomic) BOOL hasHomeIndicatorHiddenSet; +@property (nonatomic) BOOL hasOrientationSet; +@property (nonatomic) RNSScreenStackAnimation stackAnimation; +@property (nonatomic) RNSScreenStackPresentation stackPresentation; +@property (nonatomic) RNSScreenSwipeDirection swipeDirection; +@property (nonatomic, retain) NSNumber *transitionDuration; + +#if !TARGET_OS_TV +@property (nonatomic) RNSStatusBarStyle statusBarStyle; +@property (nonatomic) UIStatusBarAnimation statusBarAnimation; +@property (nonatomic) UIInterfaceOrientationMask screenOrientation; +@property (nonatomic) BOOL statusBarHidden; +@property (nonatomic) BOOL homeIndicatorHidden; +#endif +#ifdef RN_FABRIC_ENABLED +@property (weak, nonatomic) UIView *config; +@property (weak, nonatomic) UIView *reactSuperview; +@property (nonatomic, retain) RNSScreen *controller; +#else @property (nonatomic, copy) RCTDirectEventBlock onAppear; @property (nonatomic, copy) RCTDirectEventBlock onDisappear; @property (nonatomic, copy) RCTDirectEventBlock onDismissed; @@ -43,35 +85,30 @@ @property (nonatomic, retain) UIViewController *controller; @property (nonatomic, readonly) BOOL dismissed; @property (nonatomic) int activityState; -@property (nonatomic) BOOL gestureEnabled; -@property (nonatomic) RNSScreenStackAnimation stackAnimation; -@property (nonatomic) RNSScreenStackPresentation stackPresentation; @property (nonatomic) RNSScreenReplaceAnimation replaceAnimation; -@property (nonatomic) RNSScreenSwipeDirection swipeDirection; @property (nonatomic) BOOL preventNativeDismiss; -@property (nonatomic) BOOL hasOrientationSet; -@property (nonatomic) BOOL hasStatusBarStyleSet; -@property (nonatomic) BOOL hasStatusBarAnimationSet; -@property (nonatomic) BOOL hasStatusBarHiddenSet; -@property (nonatomic) BOOL hasHomeIndicatorHiddenSet; @property (nonatomic) BOOL customAnimationOnSwipe; -@property (nonatomic) BOOL fullScreenSwipeEnabled; @property (nonatomic, copy) NSDictionary *gestureResponseDistance; -@property (nonatomic, retain) NSNumber *transitionDuration; - -#if !TARGET_OS_TV -@property (nonatomic) RNSStatusBarStyle statusBarStyle; -@property (nonatomic) UIStatusBarAnimation statusBarAnimation; -@property (nonatomic) BOOL statusBarHidden; -@property (nonatomic) UIInterfaceOrientationMask screenOrientation; -@property (nonatomic) BOOL homeIndicatorHidden; #endif +#ifdef RN_FABRIC_ENABLED +- (void)notifyWillAppear; +- (void)notifyWillDisappear; +- (void)notifyAppear; +- (void)notifyDisappear; +- (void)updateBounds; +- (void)notifyDismissedWithCount:(int)dismissCount; +#else - (void)notifyFinishTransitioning; - (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingForward:(BOOL)goingForward; +#endif @end +#ifdef RN_FABRIC_ENABLED + +#else @interface UIView (RNSScreen) - (UIViewController *)parentViewController; @end +#endif diff --git a/ios/RNSScreen.m b/ios/RNSScreen.mm similarity index 65% rename from ios/RNSScreen.m rename to ios/RNSScreen.mm index 60423084f9..a2e65881be 100644 --- a/ios/RNSScreen.m +++ b/ios/RNSScreen.mm @@ -6,20 +6,71 @@ #import "RNSScreenStackHeaderConfig.h" #import "RNSScreenWindowTraits.h" -#import +#import + +// TODO: Organize imports +#ifdef RN_FABRIC_ENABLED +#import +#import +#import +#import +#import +#import "RNSConvert.h" +#import "RNSScreenStackHeaderConfigComponentView.h" +#else #import +#endif + +#import #import -@interface RNSScreenView () +#import +#import "RCTFabricComponentsPlugins.h" + +#import +#import + +@interface RNSScreenView () +#ifdef RN_FABRIC_ENABLED + +#else + +#endif @end @implementation RNSScreenView { - __weak RCTBridge *_bridge; RNSScreen *_controller; +#ifdef RN_FABRIC_ENABLED + RCTSurfaceTouchHandler *_touchHandler; + facebook::react::RNSScreenShadowNode::ConcreteState::Shared _state; +#else + __weak RCTBridge *_bridge; RCTTouchHandler *_touchHandler; CGRect _reactFrame; +#endif } +#if RN_FABRIC_ENABLED +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + _controller = [[RNSScreen alloc] initWithView:self]; + // TODO: use default props (?) + _stackAnimation = RNSScreenStackAnimationDefault; + _stackPresentation = RNSScreenStackPresentationPush; + _hasStatusBarHiddenSet = NO; + _hasStatusBarStyleSet = NO; + _gestureEnabled = YES; + _hasStatusBarAnimationSet = NO; + _hasOrientationSet = NO; + _hasHomeIndicatorHiddenSet = NO; + } + + return self; +} +#else - (instancetype)initWithBridge:(RCTBridge *)bridge { if (self = [super init]) { @@ -39,6 +90,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge return self; } +#endif - (void)reactSetFrame:(CGRect)frame { @@ -62,7 +114,16 @@ - (UIViewController *)reactViewController - (void)updateBounds { +#ifdef RN_FABRIC_ENDABLED + if (_state != nullptr) { + auto newState = facebook::react::RNSScreenState{RCTSizeFromCGSize(self.bounds.size)}; + _state->updateState(std::move(newState)); + UINavigationController *navctr = _controller.navigationController; + [navctr.view setNeedsLayout]; + } +#else [_bridge.uiManager setSize:self.bounds.size forView:self]; +#endif } // Nil will be provided when activityState is set as an animated value and we change @@ -237,6 +298,14 @@ - (void)notifyFinishTransitioning - (void)notifyDismissedWithCount:(int)dismissCount { +#ifdef RN_FABRIC_ENABLED + // If screen is already unmounted then there will be no event emitter + // it will be cleaned in prepareForRecycle + if (_eventEmitter != nullptr) { + std::dynamic_pointer_cast(_eventEmitter) + ->onDismissed(facebook::react::RNSScreenEventEmitter::OnDismissed{dismissCount : dismissCount}); + } +#else _dismissed = YES; if (self.onDismissed) { dispatch_async(dispatch_get_main_queue(), ^{ @@ -245,27 +314,55 @@ - (void)notifyDismissedWithCount:(int)dismissCount } }); } +#endif } - (void)notifyWillAppear { +#ifdef RN_FABRIC_ENABLED + // If screen is already unmounted then there will be no event emitter + // it will be cleaned in prepareForRecycle + if (_eventEmitter != nullptr) { + std::dynamic_pointer_cast(_eventEmitter) + ->onWillAppear(facebook::react::RNSScreenEventEmitter::OnWillAppear{}); + } +#else if (self.onWillAppear) { self.onWillAppear(nil); } // we do it here too because at this moment the `parentViewController` is already not nil, // so if the parent is not UINavCtr, the frame will be updated to the correct one. [self reactSetFrame:_reactFrame]; +#endif } - (void)notifyWillDisappear { +#ifdef RN_FABRIC_ENABLED + // If screen is already unmounted then there will be no event emitter + // it will be cleaned in prepareForRecycle + if (_eventEmitter != nullptr) { + std::dynamic_pointer_cast(_eventEmitter) + ->onWillDisappear(facebook::react::RNSScreenEventEmitter::OnWillDisappear{}); + } + +#else if (self.onWillDisappear) { self.onWillDisappear(nil); } +#endif } - (void)notifyAppear { +#ifdef RN_FABRIC_ENABLED + // If screen is already unmounted then there will be no event emitter + // it will be cleaned in prepareForRecycle + if (_eventEmitter != nullptr) { + std::dynamic_pointer_cast(_eventEmitter) + ->onAppear(facebook::react::RNSScreenEventEmitter::OnAppear{}); + } +#else if (self.onAppear) { dispatch_async(dispatch_get_main_queue(), ^{ if (self.onAppear) { @@ -273,13 +370,23 @@ - (void)notifyAppear } }); } +#endif } - (void)notifyDisappear { +#ifdef RN_FABRIC_ENABLED + // If screen is already unmounted then there will be no event emitter + // it will be cleaned in prepareForRecycle + if (_eventEmitter != nullptr) { + std::dynamic_pointer_cast(_eventEmitter) + ->onDisappear(facebook::react::RNSScreenEventEmitter::OnDisappear{}); + } +#else if (self.onDisappear) { self.onDisappear(nil); } +#endif } - (void)notifyDismissCancelledWithDismissCount:(int)dismissCount @@ -302,12 +409,18 @@ - (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingFor - (BOOL)isMountedUnderScreenOrReactRoot { +#ifdef RN_FABRIC_ENABLED +#define EXPECTED_VIEW RCTRootComponentView +#else +#define EXPECTED_VIEW RCTRootView +#endif for (UIView *parent = self.superview; parent != nil; parent = parent.superview) { - if ([parent isKindOfClass:[RCTRootView class]] || [parent isKindOfClass:[RNSScreenView class]]) { + if ([parent isKindOfClass:[EXPECTED_VIEW class]] || [parent isKindOfClass:[RNSScreenView class]]) { return YES; } } return NO; +#undef EXPECTED_VIEW } - (void)didMoveToWindow @@ -317,7 +430,11 @@ - (void)didMoveToWindow // root application window. if (self.window != nil && ![self isMountedUnderScreenOrReactRoot]) { if (_touchHandler == nil) { +#ifdef RN_FABRIC_ENABLED + _touchHandler = [RCTSurfaceTouchHandler new]; +#else _touchHandler = [[RCTTouchHandler alloc] initWithBridge:_bridge]; +#endif } [_touchHandler attachToView:self]; } else { @@ -325,6 +442,152 @@ - (void)didMoveToWindow } } +#ifdef RN_FABRIC_ENABLED +- (RCTSurfaceTouchHandler *)touchHandler +#else +- (RCTTouchHandler *)touchHandler +#endif +{ + if (_touchHandler != nil) { + return _touchHandler; + } + UIView *parent = [self superview]; + while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)]) + parent = parent.superview; + if (parent != nil) { + return [parent performSelector:@selector(touchHandler)]; + } + return nil; +} + +// altough it is fabric specific code ++ (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider +{ + return facebook::react::concreteComponentDescriptorProvider(); +} + +#pragma mark - Fabric specific +#ifdef RN_FABRIC_ENABLED +- (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index +{ + [super mountChildComponentView:childComponentView index:index]; + if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfigComponentView class]]) { + _config = childComponentView; + ((RNSScreenStackHeaderConfigComponentView *)childComponentView).screenView = self; + } +} + +- (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index +{ + if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfigComponentView class]]) { + _config = nil; + } + [super unmountChildComponentView:childComponentView index:index]; +} + +#pragma mark - RCTComponentViewProtocol + +- (void)prepareForRecycle +{ + [super prepareForRecycle]; + // TODO: Make sure that there is no edge case when this should be uncommented + // _controller=nil; + _state.reset(); +} + +- (void)updateProps:(facebook::react::Props::Shared const &)props + oldProps:(facebook::react::Props::Shared const &)oldProps +{ + const auto &oldScreenProps = *std::static_pointer_cast(_props); + const auto &newScreenProps = *std::static_pointer_cast(props); + + [self setFullScreenSwipeEnabled:newScreenProps.fullScreenSwipeEnabled]; + + [self setGestureEnabled:newScreenProps.gestureEnabled]; + + [self setTransitionDuration:[NSNumber numberWithInt:newScreenProps.transitionDuration]]; + + if (newScreenProps.statusBarHidden != oldScreenProps.statusBarHidden) { + [self setStatusBarHidden:newScreenProps.statusBarHidden]; + } + + if (newScreenProps.statusBarStyle != oldScreenProps.statusBarStyle) { + [self setStatusBarStyle:[RCTConvert + RNSStatusBarStyle:RCTNSStringFromStringNilIfEmpty(newScreenProps.statusBarStyle)]]; + } + + if (newScreenProps.statusBarAnimation != oldScreenProps.statusBarAnimation) { + [self setStatusBarAnimation:[RCTConvert UIStatusBarAnimation:RCTNSStringFromStringNilIfEmpty( + newScreenProps.statusBarAnimation)]]; + } + + if (newScreenProps.screenOrientation != oldScreenProps.screenOrientation) { + [self setScreenOrientation:[RCTConvert UIInterfaceOrientationMask:RCTNSStringFromStringNilIfEmpty( + newScreenProps.screenOrientation)]]; + } + + if (newScreenProps.stackPresentation != oldScreenProps.stackPresentation) { + [self + setStackPresentation:[RNSConvert RNSScreenStackPresentationFromCppEquivalent:newScreenProps.stackPresentation]]; + } + + if (newScreenProps.stackAnimation != oldScreenProps.stackAnimation) { + [self setStackAnimation:[RNSConvert RNSScreenStackAnimationFromCppEquivalent:newScreenProps.stackAnimation]]; + } + + if (newScreenProps.statusBarColor) { + [self logPropNotAvailable:@"statusBarColor"]; + } + + if (newScreenProps.statusBarTranslucent) { + [self logPropNotAvailable:@"statusBarTranslucent"]; + } + + [self setFullScreenSwipeEnabled:newScreenProps.fullScreenSwipeEnabled]; + + [self setGestureEnabled:newScreenProps.gestureEnabled]; + + if (newScreenProps.statusBarHidden != oldScreenProps.statusBarHidden) { + [self setStatusBarHidden:newScreenProps.statusBarHidden]; + } + + if (newScreenProps.statusBarStyle != oldScreenProps.statusBarStyle) { + [self setStatusBarStyle:[RCTConvert RNSStatusBarStyle:[self stringToPropValue:newScreenProps.statusBarStyle]]]; + } + + if (newScreenProps.statusBarAnimation != oldScreenProps.statusBarAnimation) { + [self setStatusBarAnimation:[RCTConvert + UIStatusBarAnimation:[self stringToPropValue:newScreenProps.statusBarAnimation]]]; + } + + if (newScreenProps.screenOrientation != oldScreenProps.screenOrientation) { + [self + setScreenOrientation:[RCTConvert + UIInterfaceOrientationMask:[self stringToPropValue:newScreenProps.screenOrientation]]]; + } + + if (newScreenProps.statusBarColor) { + [self logPropNotAvailable:@"statusBarColor"]; + } + + if (newScreenProps.statusBarTranslucent) { + [self logPropNotAvailable:@"statusBarTranslucent"]; + } + + [super updateProps:props oldProps:oldProps]; + + _fullScreenSwipeEnabled = newScreenProps.fullScreenSwipeEnabled; + _gestureEnabled = newScreenProps.gestureEnabled; +} + +- (void)updateState:(facebook::react::State::Shared const &)state + oldState:(facebook::react::State::Shared const &)oldState +{ + _state = std::static_pointer_cast(state); +} + +#pragma mark - Paper specific +#else - (void)presentationControllerWillDismiss:(UIPresentationController *)presentationController { // We need to call both "cancel" and "reset" here because RN's gesture recognizer @@ -341,20 +604,6 @@ - (void)presentationControllerWillDismiss:(UIPresentationController *)presentati [_touchHandler reset]; } -- (RCTTouchHandler *)touchHandler -{ - if (_touchHandler != nil) { - return _touchHandler; - } - UIView *parent = [self superview]; - while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)]) - parent = parent.superview; - if (parent != nil) { - return [parent performSelector:@selector(touchHandler)]; - } - return nil; -} - - (BOOL)presentationControllerShouldDismiss:(UIPresentationController *)presentationController { if (_preventNativeDismiss) { @@ -375,11 +624,215 @@ - (void)invalidate { _controller = nil; } +#endif @end +Class RNSScreenCls(void) +{ + return RNSScreenView.class; +} + #pragma mark - RNSScreen +#ifdef RN_FABRIC_ENABLED + +@implementation RNSScreen { + RNSScreenView *_initialView; +} + +- (instancetype)initWithView:(UIView *)view +{ + if (self = [super init]) { + self.view = view; + if ([view isKindOfClass:[RNSScreenView class]]) { + _initialView = (RNSScreenView *)view; + } else { + RCTLogError(@"ScreenController can only be initialized with ScreenComponentView"); + } + } + return self; +} + +- (void)setViewToSnapshot:(UIView *)snapshot +{ + [self.view removeFromSuperview]; + self.view = snapshot; +} + +- (void)resetViewToScreen +{ + [self.view removeFromSuperview]; + self.view = _initialView; +} + +// TODO: Find out why this is executed when screen is going out +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + [RNSScreenWindowTraits updateWindowTraits]; + [_initialView notifyWillAppear]; +} + +- (void)viewWillDisappear:(BOOL)animated +{ + [super viewWillDisappear:animated]; + [_initialView notifyWillDisappear]; +} + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + [_initialView notifyAppear]; +} + +- (void)viewDidDisappear:(BOOL)animated +{ + [super viewDidDisappear:animated]; + [_initialView notifyDisappear]; + if (self.parentViewController == nil && self.presentingViewController == nil) { + // screen dismissed, send event + [_initialView notifyDismissedWithCount:1]; + } +} + +- (void)viewDidLayoutSubviews +{ + [super viewDidLayoutSubviews]; + BOOL isDisplayedWithinUINavController = [self.parentViewController isKindOfClass:[UINavigationController class]]; + if (isDisplayedWithinUINavController) { + [_initialView updateBounds]; + } +} + +#if !TARGET_OS_TV +// if the returned vc is a child, it means that it can provide config; +// if the returned vc is self, it means that there is no child for config and self has config to provide, +// so we return self which results in asking self for preferredStatusBarStyle/Animation etc.; +// if the returned vc is nil, it means none of children could provide config and self does not have config either, +// so if it was asked by parent, it will fallback to parent's option, or use default option if it is the top Screen +- (UIViewController *)findChildVCForConfigAndTrait:(RNSWindowTrait)trait includingModals:(BOOL)includingModals +{ + UIViewController *lastViewController = [[self childViewControllers] lastObject]; + if ([self.presentedViewController isKindOfClass:[RNSScreen class]]) { + lastViewController = self.presentedViewController; + // we don't want to allow controlling of status bar appearance when we present non-fullScreen modal + // and it is not possible if `modalPresentationCapturesStatusBarAppearance` is not set to YES, so even + // if we went into a modal here and ask it, it wouldn't take any effect. For fullScreen modals, the system + // asks them by itself, so we can stop traversing here. + // for screen orientation, we need to start the search again from that modal + return !includingModals + ? nil + : [(RNSScreen *)lastViewController findChildVCForConfigAndTrait:trait includingModals:includingModals] + ?: lastViewController; + } + + UIViewController *selfOrNil = [self hasTraitSet:trait] ? self : nil; + if (lastViewController == nil) { + return selfOrNil; + } else { + if ([lastViewController conformsToProtocol:@protocol(RNScreensViewControllerDelegate)]) { + // If there is a child (should be VC of ScreenContainer or ScreenStack), that has a child that could provide the + // trait, we recursively go into its findChildVCForConfig, and if one of the children has the trait set, we return + // it, otherwise we return self if this VC has config, and nil if it doesn't we use + // `childViewControllerForStatusBarStyle` for all options since the behavior is the same for all of them + UIViewController *childScreen = [lastViewController childViewControllerForStatusBarStyle]; + if ([childScreen isKindOfClass:[RNSScreen class]]) { + return [(RNSScreen *)childScreen findChildVCForConfigAndTrait:trait includingModals:includingModals] + ?: selfOrNil; + } else { + return selfOrNil; + } + } else { + // child vc is not from this library, so we don't ask it + return selfOrNil; + } + } +} + +- (BOOL)hasTraitSet:(RNSWindowTrait)trait +{ + switch (trait) { + case RNSWindowTraitStyle: { + return ((RNSScreenView *)self.view).hasStatusBarStyleSet; + } + case RNSWindowTraitAnimation: { + return ((RNSScreenView *)self.view).hasStatusBarAnimationSet; + } + case RNSWindowTraitHidden: { + return ((RNSScreenView *)self.view).hasStatusBarHiddenSet; + } + case RNSWindowTraitOrientation: { + return ((RNSScreenView *)self.view).hasOrientationSet; + } + case RNSWindowTraitHomeIndicatorHidden: { + return ((RNSScreenView *)self.view).hasHomeIndicatorHiddenSet; + } + default: { + RCTLogError(@"Unknown trait passed: %d", (int)trait); + } + } + return NO; +} + +- (UIViewController *)childViewControllerForStatusBarHidden +{ + UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitHidden includingModals:NO]; + return vc == self ? nil : vc; +} + +- (BOOL)prefersStatusBarHidden +{ + return ((RNSScreenView *)self.view).statusBarHidden; +} + +- (UIViewController *)childViewControllerForStatusBarStyle +{ + UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitStyle includingModals:NO]; + return vc == self ? nil : vc; +} + +- (UIStatusBarStyle)preferredStatusBarStyle +{ + return [RNSScreenWindowTraits statusBarStyleForRNSStatusBarStyle:((RNSScreenView *)self.view).statusBarStyle]; +} + +- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation +{ + UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitAnimation includingModals:NO]; + + if ([vc isKindOfClass:[RNSScreen class]]) { + return ((RNSScreenView *)vc.view).statusBarAnimation; + } + return UIStatusBarAnimationFade; +} + +- (UIInterfaceOrientationMask)supportedInterfaceOrientations +{ + UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitOrientation includingModals:YES]; + + if ([vc isKindOfClass:[RNSScreen class]]) { + return ((RNSScreenView *)vc.view).screenOrientation; + } + return UIInterfaceOrientationMaskAllButUpsideDown; +} + +- (UIViewController *)childViewControllerForHomeIndicatorAutoHidden +{ + UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitHomeIndicatorHidden includingModals:YES]; + return vc == self ? nil : vc; +} + +- (BOOL)prefersHomeIndicatorAutoHidden +{ + return ((RNSScreenView *)self.view).homeIndicatorHidden; +} +#endif + +@end + +#else + @implementation RNSScreen { __weak id _previousFirstResponder; CGRect _lastViewFrame; @@ -782,6 +1235,8 @@ - (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingFor @end +#endif + @implementation RNSScreenManager RCT_EXPORT_MODULE() @@ -824,6 +1279,16 @@ - (UIView *)view @implementation RCTConvert (RNSScreen) +RCT_ENUM_CONVERTER( + UIStatusBarAnimation, + (@{ + @"none" : @(UIStatusBarAnimationNone), + @"fade" : @(UIStatusBarAnimationFade), + @"slide" : @(UIStatusBarAnimationSlide) + }), + UIStatusBarAnimationNone, + integerValue) + RCT_ENUM_CONVERTER( RNSScreenStackPresentation, (@{ diff --git a/ios/RNSScreenComponentView.h b/ios/RNSScreenComponentView.h deleted file mode 100644 index e4a05850bf..0000000000 --- a/ios/RNSScreenComponentView.h +++ /dev/null @@ -1,57 +0,0 @@ -#import - -#import - -#import "RNSEnums.h" -#import "RNSScreenController.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface RCTConvert (RNSScreenComponentView) - -+ (RNSScreenStackPresentation)RNSScreenStackPresentation:(id)json; - -#if !TARGET_OS_TV -+ (RNSStatusBarStyle)RNSStatusBarStyle:(id)json; -+ (UIStatusBarAnimation)UIStatusBarAnimation:(id)json; -+ (UIInterfaceOrientationMask)UIInterfaceOrientationMask:(id)json; -#endif - -@end - -@interface RNSScreenComponentView : RCTViewComponentView - -@property (weak, nonatomic) UIView *reactSuperview; -@property (weak, nonatomic) UIView *config; -@property (nonatomic, retain) RNSScreenController *controller; - -@property (nonatomic) BOOL fullScreenSwipeEnabled; -@property (nonatomic) BOOL gestureEnabled; -@property (nonatomic) BOOL hasStatusBarHiddenSet; -@property (nonatomic) BOOL hasStatusBarStyleSet; -@property (nonatomic) BOOL hasStatusBarAnimationSet; -@property (nonatomic) BOOL hasHomeIndicatorHiddenSet; -@property (nonatomic) BOOL hasOrientationSet; -@property (nonatomic) RNSScreenSwipeDirection swipeDirection; -@property (nonatomic) RNSScreenStackPresentation stackPresentation; -@property (nonatomic) RNSScreenStackAnimation stackAnimation; -@property (nonatomic, retain) NSNumber *transitionDuration; - -#if !TARGET_OS_TV -@property (nonatomic) BOOL statusBarHidden; -@property (nonatomic) BOOL homeIndicatorHidden; -@property (nonatomic) RNSStatusBarStyle statusBarStyle; -@property (nonatomic) UIInterfaceOrientationMask screenOrientation; -@property (nonatomic) UIStatusBarAnimation statusBarAnimation; -#endif - -- (void)notifyWillAppear; -- (void)notifyWillDisappear; -- (void)notifyAppear; -- (void)notifyDisappear; -- (void)updateBounds; -- (void)notifyDismissedWithCount:(int)dismissCount; - -@end - -NS_ASSUME_NONNULL_END diff --git a/ios/RNSScreenComponentView.mm b/ios/RNSScreenComponentView.mm deleted file mode 100644 index c07d7e4b83..0000000000 --- a/ios/RNSScreenComponentView.mm +++ /dev/null @@ -1,485 +0,0 @@ -#import "RNSScreenComponentView.h" -#import "RNSConvert.h" -#import "RNSScreenStackHeaderConfigComponentView.h" -#import "RNSScreenWindowTraits.h" - -#import - -#import -#import -#import -#import - -#import "RCTFabricComponentsPlugins.h" - -#import -#import - -@interface RNSScreenComponentView () -@end - -@implementation RNSScreenComponentView { - RNSScreenController *_controller; - facebook::react::RNSScreenShadowNode::ConcreteState::Shared _state; - RCTSurfaceTouchHandler *_touchHandler; -} - -- (instancetype)initWithFrame:(CGRect)frame -{ - if (self = [super initWithFrame:frame]) { - static const auto defaultProps = std::make_shared(); - _props = defaultProps; - _controller = [[RNSScreenController alloc] initWithView:self]; - // TODO: use default props (?) - _stackAnimation = RNSScreenStackAnimationDefault; - _stackPresentation = RNSScreenStackPresentationPush; - _hasStatusBarHiddenSet = NO; - _hasStatusBarStyleSet = NO; - _gestureEnabled = YES; - _hasStatusBarAnimationSet = NO; - _hasOrientationSet = NO; - _hasHomeIndicatorHiddenSet = NO; - } - - return self; -} - -- (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index -{ - [super mountChildComponentView:childComponentView index:index]; - if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfigComponentView class]]) { - _config = childComponentView; - ((RNSScreenStackHeaderConfigComponentView *)childComponentView).screenView = self; - } -} - -- (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index -{ - if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfigComponentView class]]) { - _config = nil; - } - [super unmountChildComponentView:childComponentView index:index]; -} - -- (void)updateBounds -{ - if (_state != nullptr) { - auto newState = facebook::react::RNSScreenState{RCTSizeFromCGSize(self.bounds.size)}; - _state->updateState(std::move(newState)); - UINavigationController *navctr = _controller.navigationController; - [navctr.view setNeedsLayout]; - } -} - -- (UIView *)reactSuperview -{ - return _reactSuperview; -} - -- (UIViewController *)reactViewController -{ - return _controller; -} - -- (void)notifyWillAppear -{ - // If screen is already unmounted then there will be no event emitter - // it will be cleaned in prepareForRecycle - if (_eventEmitter != nullptr) { - std::dynamic_pointer_cast(_eventEmitter) - ->onWillAppear(facebook::react::RNSScreenEventEmitter::OnWillAppear{}); - } -} - -- (void)notifyWillDisappear -{ - // If screen is already unmounted then there will be no event emitter - // it will be cleaned in prepareForRecycle - if (_eventEmitter != nullptr) { - std::dynamic_pointer_cast(_eventEmitter) - ->onWillDisappear(facebook::react::RNSScreenEventEmitter::OnWillDisappear{}); - } -} - -- (void)notifyAppear -{ - // If screen is already unmounted then there will be no event emitter - // it will be cleaned in prepareForRecycle - if (_eventEmitter != nullptr) { - std::dynamic_pointer_cast(_eventEmitter) - ->onAppear(facebook::react::RNSScreenEventEmitter::OnAppear{}); - } -} - -- (void)notifyDismissedWithCount:(int)dismissCount -{ - // If screen is already unmounted then there will be no event emitter - // it will be cleaned in prepareForRecycle - if (_eventEmitter != nullptr) { - std::dynamic_pointer_cast(_eventEmitter) - ->onDismissed(facebook::react::RNSScreenEventEmitter::OnDismissed{dismissCount : dismissCount}); - } -} - -- (void)notifyDisappear -{ - // If screen is already unmounted then there will be no event emitter - // it will be cleaned in prepareForRecycle - if (_eventEmitter != nullptr) { - std::dynamic_pointer_cast(_eventEmitter) - ->onDisappear(facebook::react::RNSScreenEventEmitter::OnDisappear{}); - } -} - -- (void)setStackPresentation:(RNSScreenStackPresentation)stackPresentation -{ - switch (stackPresentation) { - case RNSScreenStackPresentationModal: -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \ - __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 - if (@available(iOS 13.0, tvOS 13.0, *)) { - _controller.modalPresentationStyle = UIModalPresentationAutomatic; - } else { - _controller.modalPresentationStyle = UIModalPresentationFullScreen; - } -#else - _controller.modalPresentationStyle = UIModalPresentationFullScreen; -#endif - break; - case RNSScreenStackPresentationFullScreenModal: - _controller.modalPresentationStyle = UIModalPresentationFullScreen; - break; -#if !TARGET_OS_TV - case RNSScreenStackPresentationFormSheet: - _controller.modalPresentationStyle = UIModalPresentationFormSheet; - break; -#endif - case RNSScreenStackPresentationTransparentModal: - _controller.modalPresentationStyle = UIModalPresentationOverFullScreen; - break; - case RNSScreenStackPresentationContainedModal: - _controller.modalPresentationStyle = UIModalPresentationCurrentContext; - break; - case RNSScreenStackPresentationContainedTransparentModal: - _controller.modalPresentationStyle = UIModalPresentationOverCurrentContext; - break; - case RNSScreenStackPresentationPush: - // ignored, we only need to keep in mind not to set presentation delegate - break; - } - // There is a bug in UIKit which causes retain loop when presentationController is accessed for a - // controller that is not going to be presented modally. We therefore need to avoid setting the - // delegate for screens presented using push. This also means that when controller is updated from - // modal to push type, this may cause memory leak, we warn about that as well. - if (stackPresentation != RNSScreenStackPresentationPush) { - // `modalPresentationStyle` must be set before accessing `presentationController` - // otherwise a default controller will be created and cannot be changed after. - // Documented here: - // https://developer.apple.com/documentation/uikit/uiviewcontroller/1621426-presentationcontroller?language=objc - _controller.presentationController.delegate = self; - } else if (_stackPresentation != RNSScreenStackPresentationPush) { - RCTLogError( - @"Screen presentation updated from modal to push, this may likely result in a screen object leakage. If you need to change presentation style create a new screen object instead"); - } - _stackPresentation = stackPresentation; -} - -- (void)setStackAnimation:(RNSScreenStackAnimation)stackAnimation -{ - _stackAnimation = stackAnimation; - - switch (stackAnimation) { - case RNSScreenStackAnimationFade: - _controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; - break; -#if !TARGET_OS_TV - case RNSScreenStackAnimationFlip: - _controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; - break; -#endif - case RNSScreenStackAnimationNone: - case RNSScreenStackAnimationDefault: - case RNSScreenStackAnimationSimplePush: - case RNSScreenStackAnimationSlideFromBottom: - case RNSScreenStackAnimationFadeFromBottom: - // Default - break; - } -} - -- (void)setGestureEnabled:(BOOL)gestureEnabled -{ -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \ - __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 - if (@available(iOS 13.0, tvOS 13.0, *)) { - _controller.modalInPresentation = !gestureEnabled; - } -#endif - _gestureEnabled = gestureEnabled; -} - -#if !TARGET_OS_TV -- (void)setStatusBarHidden:(BOOL)statusBarHidden -{ - _statusBarHidden = statusBarHidden; - _hasStatusBarHiddenSet = YES; - [RNSScreenWindowTraits assertViewControllerBasedStatusBarAppearenceSet]; - [RNSScreenWindowTraits updateStatusBarAppearance]; -} - -- (void)setStatusBarStyle:(RNSStatusBarStyle)statusBarStyle -{ - _hasStatusBarStyleSet = YES; - _statusBarStyle = statusBarStyle; - [RNSScreenWindowTraits assertViewControllerBasedStatusBarAppearenceSet]; - [RNSScreenWindowTraits updateStatusBarAppearance]; -} - -- (void)setStatusBarAnimation:(UIStatusBarAnimation)statusBarAnimation -{ - _hasStatusBarAnimationSet = YES; - _statusBarAnimation = statusBarAnimation; - [RNSScreenWindowTraits assertViewControllerBasedStatusBarAppearenceSet]; -} - -- (void)setScreenOrientation:(UIInterfaceOrientationMask)screenOrientation -{ - _hasOrientationSet = YES; - _screenOrientation = screenOrientation; - [RNSScreenWindowTraits enforceDesiredDeviceOrientation]; -} - -- (void)setHomeIndicatorHidden:(BOOL)homeIndicatorHidden -{ - _hasHomeIndicatorHiddenSet = YES; - _homeIndicatorHidden = homeIndicatorHidden; - [RNSScreenWindowTraits updateHomeIndicatorAutoHidden]; -} -#endif - -- (BOOL)isMountedUnderScreenOrReactRoot -{ - for (UIView *parent = self.superview; parent != nil; parent = parent.superview) { - if ([parent isKindOfClass:[RCTRootComponentView class]] || [parent isKindOfClass:[RNSScreenComponentView class]]) { - return YES; - } - } - return NO; -} - -- (void)didMoveToWindow -{ - if (self.window != nil && ![self isMountedUnderScreenOrReactRoot]) { - if (_touchHandler == nil) { - _touchHandler = [RCTSurfaceTouchHandler new]; - } - [_touchHandler attachToView:self]; - } else { - [_touchHandler detachFromView:self]; - } -} - -- (RCTSurfaceTouchHandler *)touchHandler -{ - if (_touchHandler != nil) { - return _touchHandler; - } - UIView *parent = [self superview]; - while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)]) - parent = parent.superview; - - if (parent != nil) { - return [parent performSelector:@selector(touchHandler)]; - } - return nil; -} - -#pragma mark - RCTComponentViewProtocol - -- (void)prepareForRecycle -{ - [super prepareForRecycle]; - // TODO: Make sure that there is no edge case when this should be uncommented - // _controller=nil; - _state.reset(); -} - -+ (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider -{ - return facebook::react::concreteComponentDescriptorProvider(); -} - -- (void)updateProps:(facebook::react::Props::Shared const &)props - oldProps:(facebook::react::Props::Shared const &)oldProps -{ - const auto &oldScreenProps = *std::static_pointer_cast(_props); - const auto &newScreenProps = *std::static_pointer_cast(props); - - [self setFullScreenSwipeEnabled:newScreenProps.fullScreenSwipeEnabled]; - - [self setGestureEnabled:newScreenProps.gestureEnabled]; - - [self setTransitionDuration:[NSNumber numberWithInt:newScreenProps.transitionDuration]]; - - if (newScreenProps.statusBarHidden != oldScreenProps.statusBarHidden) { - [self setStatusBarHidden:newScreenProps.statusBarHidden]; - } - - if (newScreenProps.statusBarStyle != oldScreenProps.statusBarStyle) { - [self setStatusBarStyle:[RCTConvert - RNSStatusBarStyle:RCTNSStringFromStringNilIfEmpty(newScreenProps.statusBarStyle)]]; - } - - if (newScreenProps.statusBarAnimation != oldScreenProps.statusBarAnimation) { - [self setStatusBarAnimation:[RCTConvert UIStatusBarAnimation:RCTNSStringFromStringNilIfEmpty( - newScreenProps.statusBarAnimation)]]; - } - - if (newScreenProps.screenOrientation != oldScreenProps.screenOrientation) { - [self setScreenOrientation:[RCTConvert UIInterfaceOrientationMask:RCTNSStringFromStringNilIfEmpty( - newScreenProps.screenOrientation)]]; - } - - if (newScreenProps.stackPresentation != oldScreenProps.stackPresentation) { - [self - setStackPresentation:[RNSConvert RNSScreenStackPresentationFromCppEquivalent:newScreenProps.stackPresentation]]; - } - - if (newScreenProps.stackAnimation != oldScreenProps.stackAnimation) { - [self setStackAnimation:[RNSConvert RNSScreenStackAnimationFromCppEquivalent:newScreenProps.stackAnimation]]; - } - - if (newScreenProps.statusBarColor) { - [self logPropNotAvailable:@"statusBarColor"]; - } - - if (newScreenProps.statusBarTranslucent) { - [self logPropNotAvailable:@"statusBarTranslucent"]; - } - - [self setFullScreenSwipeEnabled:newScreenProps.fullScreenSwipeEnabled]; - - [self setGestureEnabled:newScreenProps.gestureEnabled]; - - if (newScreenProps.statusBarHidden != oldScreenProps.statusBarHidden) { - [self setStatusBarHidden:newScreenProps.statusBarHidden]; - } - - if (newScreenProps.statusBarStyle != oldScreenProps.statusBarStyle) { - [self setStatusBarStyle:[RCTConvert RNSStatusBarStyle:[self stringToPropValue:newScreenProps.statusBarStyle]]]; - } - - if (newScreenProps.statusBarAnimation != oldScreenProps.statusBarAnimation) { - [self setStatusBarAnimation:[RCTConvert - UIStatusBarAnimation:[self stringToPropValue:newScreenProps.statusBarAnimation]]]; - } - - if (newScreenProps.screenOrientation != oldScreenProps.screenOrientation) { - [self - setScreenOrientation:[RCTConvert - UIInterfaceOrientationMask:[self stringToPropValue:newScreenProps.screenOrientation]]]; - } - - if (newScreenProps.statusBarColor) { - [self logPropNotAvailable:@"statusBarColor"]; - } - - if (newScreenProps.statusBarTranslucent) { - [self logPropNotAvailable:@"statusBarTranslucent"]; - } - - [super updateProps:props oldProps:oldProps]; - - _fullScreenSwipeEnabled = newScreenProps.fullScreenSwipeEnabled; - _gestureEnabled = newScreenProps.gestureEnabled; -} - -- (void)updateState:(facebook::react::State::Shared const &)state - oldState:(facebook::react::State::Shared const &)oldState -{ - _state = std::static_pointer_cast(state); -} - -#pragma mark - Util - -- (void)logPropNotAvailable:(NSString *)propName -{ - NSLog(@"%@ prop not available on iOS", propName); -} - -- (NSString *)stringToPropValue:(std::string)value -{ - if (value.empty()) - return nil; - return [[NSString alloc] initWithUTF8String:value.c_str()]; -} -@end - -Class RNSScreenCls(void) -{ - return RNSScreenComponentView.class; -} - -@implementation RCTConvert (RNSScreenComponentView) - -RCT_ENUM_CONVERTER( - UIStatusBarAnimation, - (@{ - @"none" : @(UIStatusBarAnimationNone), - @"fade" : @(UIStatusBarAnimationFade), - @"slide" : @(UIStatusBarAnimationSlide) - }), - UIStatusBarAnimationNone, - integerValue) - -RCT_ENUM_CONVERTER( - RNSScreenStackPresentation, - (@{ - @"push" : @(RNSScreenStackPresentationPush), - @"modal" : @(RNSScreenStackPresentationModal), - @"fullScreenModal" : @(RNSScreenStackPresentationFullScreenModal), - @"formSheet" : @(RNSScreenStackPresentationFormSheet), - @"containedModal" : @(RNSScreenStackPresentationContainedModal), - @"transparentModal" : @(RNSScreenStackPresentationTransparentModal), - @"containedTransparentModal" : @(RNSScreenStackPresentationContainedTransparentModal) - }), - RNSScreenStackPresentationPush, - integerValue) - -#if !TARGET_OS_TV -RCT_ENUM_CONVERTER( - RNSStatusBarStyle, - (@{ - @"auto" : @(RNSStatusBarStyleAuto), - @"inverted" : @(RNSStatusBarStyleInverted), - @"light" : @(RNSStatusBarStyleLight), - @"dark" : @(RNSStatusBarStyleDark), - }), - RNSStatusBarStyleAuto, - integerValue) - -+ (UIInterfaceOrientationMask)UIInterfaceOrientationMask:(id)json -{ - json = [self NSString:json]; - if ([json isEqualToString:@"default"]) { - return UIInterfaceOrientationMaskAllButUpsideDown; - } else if ([json isEqualToString:@"all"]) { - return UIInterfaceOrientationMaskAll; - } else if ([json isEqualToString:@"portrait"]) { - return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown; - } else if ([json isEqualToString:@"portrait_up"]) { - return UIInterfaceOrientationMaskPortrait; - } else if ([json isEqualToString:@"portrait_down"]) { - return UIInterfaceOrientationMaskPortraitUpsideDown; - } else if ([json isEqualToString:@"landscape"]) { - return UIInterfaceOrientationMaskLandscape; - } else if ([json isEqualToString:@"landscape_left"]) { - return UIInterfaceOrientationMaskLandscapeLeft; - } else if ([json isEqualToString:@"landscape_right"]) { - return UIInterfaceOrientationMaskLandscapeRight; - } - return UIInterfaceOrientationMaskAllButUpsideDown; -} -#endif - -@end diff --git a/ios/RNSScreenController.h b/ios/RNSScreenController.h deleted file mode 100644 index 6ce38cba82..0000000000 --- a/ios/RNSScreenController.h +++ /dev/null @@ -1,12 +0,0 @@ -#import -#import "RNSScreenContainer.h" - -@interface RNSScreenController : UIViewController - -- (instancetype)initWithView:(UIView *)view; -- (void)setViewToSnapshot:(UIView *)snapshot; -- (void)resetViewToScreen; - -- (UIViewController *)findChildVCForConfigAndTrait:(RNSWindowTrait)trait includingModals:(BOOL)includingModals; - -@end diff --git a/ios/RNSScreenController.mm b/ios/RNSScreenController.mm deleted file mode 100644 index b4f4aaa789..0000000000 --- a/ios/RNSScreenController.mm +++ /dev/null @@ -1,198 +0,0 @@ -#import -#import "RNSScreenComponentView.h" -#import "RNSScreenWindowTraits.h" - -@implementation RNSScreenController { - RNSScreenComponentView *_initialView; -} - -- (instancetype)initWithView:(UIView *)view -{ - if (self = [super init]) { - self.view = view; - if ([view isKindOfClass:[RNSScreenComponentView class]]) { - _initialView = (RNSScreenComponentView *)view; - } else { - RCTLogError(@"ScreenController can only be initialized with ScreenComponentView"); - } - } - return self; -} - -- (void)setViewToSnapshot:(UIView *)snapshot -{ - [self.view removeFromSuperview]; - self.view = snapshot; -} - -- (void)resetViewToScreen -{ - [self.view removeFromSuperview]; - self.view = _initialView; -} - -// TODO: Find out why this is executed when screen is going out -- (void)viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; - [RNSScreenWindowTraits updateWindowTraits]; - [_initialView notifyWillAppear]; -} - -- (void)viewWillDisappear:(BOOL)animated -{ - [super viewWillDisappear:animated]; - [_initialView notifyWillDisappear]; -} - -- (void)viewDidAppear:(BOOL)animated -{ - [super viewDidAppear:animated]; - [_initialView notifyAppear]; -} - -- (void)viewDidDisappear:(BOOL)animated -{ - [super viewDidDisappear:animated]; - [_initialView notifyDisappear]; - if (self.parentViewController == nil && self.presentingViewController == nil) { - // screen dismissed, send event - [_initialView notifyDismissedWithCount:1]; - } -} - -- (void)viewDidLayoutSubviews -{ - [super viewDidLayoutSubviews]; - BOOL isDisplayedWithinUINavController = [self.parentViewController isKindOfClass:[UINavigationController class]]; - if (isDisplayedWithinUINavController) { - [_initialView updateBounds]; - } -} - -#if !TARGET_OS_TV -// if the returned vc is a child, it means that it can provide config; -// if the returned vc is self, it means that there is no child for config and self has config to provide, -// so we return self which results in asking self for preferredStatusBarStyle/Animation etc.; -// if the returned vc is nil, it means none of children could provide config and self does not have config either, -// so if it was asked by parent, it will fallback to parent's option, or use default option if it is the top Screen -- (UIViewController *)findChildVCForConfigAndTrait:(RNSWindowTrait)trait includingModals:(BOOL)includingModals -{ - UIViewController *lastViewController = [[self childViewControllers] lastObject]; - if ([self.presentedViewController isKindOfClass:[RNSScreenController class]]) { - lastViewController = self.presentedViewController; - // we don't want to allow controlling of status bar appearance when we present non-fullScreen modal - // and it is not possible if `modalPresentationCapturesStatusBarAppearance` is not set to YES, so even - // if we went into a modal here and ask it, it wouldn't take any effect. For fullScreen modals, the system - // asks them by itself, so we can stop traversing here. - // for screen orientation, we need to start the search again from that modal - return !includingModals - ? nil - : [(RNSScreenController *)lastViewController findChildVCForConfigAndTrait:trait includingModals:includingModals] - ?: lastViewController; - } - - UIViewController *selfOrNil = [self hasTraitSet:trait] ? self : nil; - if (lastViewController == nil) { - return selfOrNil; - } else { - if ([lastViewController conformsToProtocol:@protocol(RNScreensViewControllerDelegate)]) { - // If there is a child (should be VC of ScreenContainer or ScreenStack), that has a child that could provide the - // trait, we recursively go into its findChildVCForConfig, and if one of the children has the trait set, we return - // it, otherwise we return self if this VC has config, and nil if it doesn't we use - // `childViewControllerForStatusBarStyle` for all options since the behavior is the same for all of them - UIViewController *childScreen = [lastViewController childViewControllerForStatusBarStyle]; - if ([childScreen isKindOfClass:[RNSScreenController class]]) { - return [(RNSScreenController *)childScreen findChildVCForConfigAndTrait:trait includingModals:includingModals] - ?: selfOrNil; - } else { - return selfOrNil; - } - } else { - // child vc is not from this library, so we don't ask it - return selfOrNil; - } - } -} - -- (BOOL)hasTraitSet:(RNSWindowTrait)trait -{ - switch (trait) { - case RNSWindowTraitStyle: { - return ((RNSScreenComponentView *)self.view).hasStatusBarStyleSet; - } - case RNSWindowTraitAnimation: { - return ((RNSScreenComponentView *)self.view).hasStatusBarAnimationSet; - } - case RNSWindowTraitHidden: { - return ((RNSScreenComponentView *)self.view).hasStatusBarHiddenSet; - } - case RNSWindowTraitOrientation: { - return ((RNSScreenComponentView *)self.view).hasOrientationSet; - } - case RNSWindowTraitHomeIndicatorHidden: { - return ((RNSScreenComponentView *)self.view).hasHomeIndicatorHiddenSet; - } - default: { - RCTLogError(@"Unknown trait passed: %d", (int)trait); - } - } - return NO; -} - -- (UIViewController *)childViewControllerForStatusBarHidden -{ - UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitHidden includingModals:NO]; - return vc == self ? nil : vc; -} - -- (BOOL)prefersStatusBarHidden -{ - return ((RNSScreenComponentView *)self.view).statusBarHidden; -} - -- (UIViewController *)childViewControllerForStatusBarStyle -{ - UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitStyle includingModals:NO]; - return vc == self ? nil : vc; -} - -- (UIStatusBarStyle)preferredStatusBarStyle -{ - return - [RNSScreenWindowTraits statusBarStyleForRNSStatusBarStyle:((RNSScreenComponentView *)self.view).statusBarStyle]; -} - -- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation -{ - UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitAnimation includingModals:NO]; - - if ([vc isKindOfClass:[RNSScreenController class]]) { - return ((RNSScreenComponentView *)vc.view).statusBarAnimation; - } - return UIStatusBarAnimationFade; -} - -- (UIInterfaceOrientationMask)supportedInterfaceOrientations -{ - UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitOrientation includingModals:YES]; - - if ([vc isKindOfClass:[RNSScreenController class]]) { - return ((RNSScreenComponentView *)vc.view).screenOrientation; - } - return UIInterfaceOrientationMaskAllButUpsideDown; -} - -- (UIViewController *)childViewControllerForHomeIndicatorAutoHidden -{ - UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitHomeIndicatorHidden includingModals:YES]; - return vc == self ? nil : vc; -} - -- (BOOL)prefersHomeIndicatorAutoHidden -{ - return ((RNSScreenComponentView *)self.view).homeIndicatorHidden; -} -#endif - -@end From 6dd5347b1c02adcd952bab9c67a9db09dac27a8a Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 8 Apr 2022 15:05:40 +0200 Subject: [PATCH 003/156] refract: Rename dependencies to make previous change work --- ios/RNSScreenStackAnimator.m | 18 ++---- ios/RNSScreenStackComponentView.mm | 59 ++++++++++++------- ios/RNSScreenStackHeaderConfigComponentView.h | 4 +- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/ios/RNSScreenStackAnimator.m b/ios/RNSScreenStackAnimator.m index fb48a24e79..efc10ff8c5 100644 --- a/ios/RNSScreenStackAnimator.m +++ b/ios/RNSScreenStackAnimator.m @@ -1,13 +1,7 @@ #import "RNSScreenStackAnimator.h" #import "RNSScreenStack.h" -#if RN_FABRIC_ENABLED -#import "RNSScreenComponentView.h" -#define RNSView RNSScreenComponentView -#else #import "RNSScreen.h" -#define RNSView RNSScreenView -#endif // proportions to default transition duration static const float RNSSlideOpenTransitionDurationProportion = 1; @@ -32,15 +26,15 @@ - (instancetype)initWithOperation:(UINavigationControllerOperation)operation - (NSTimeInterval)transitionDuration:(id)transitionContext { - RNSView *screen; + RNSScreenView *screen; if (_operation == UINavigationControllerOperationPush) { UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; - screen = (RNSView *)toViewController.view; + screen = (RNSScreenView *)toViewController.view; } else if (_operation == UINavigationControllerOperationPop) { UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; - screen = (RNSView *)fromViewController.view; + screen = (RNSScreenView *)fromViewController.view; } if (screen != nil && screen.stackAnimation == RNSScreenStackAnimationNone) { @@ -62,11 +56,11 @@ - (void)animateTransition:(id)transitionCo [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; toViewController.view.frame = [transitionContext finalFrameForViewController:toViewController]; - RNSView *screen; + RNSScreenView *screen; if (_operation == UINavigationControllerOperationPush) { - screen = (RNSView *)toViewController.view; + screen = (RNSScreenView *)toViewController.view; } else if (_operation == UINavigationControllerOperationPop) { - screen = (RNSView *)fromViewController.view; + screen = (RNSScreenView *)fromViewController.view; } if (screen != nil) { diff --git a/ios/RNSScreenStackComponentView.mm b/ios/RNSScreenStackComponentView.mm index 25a371407b..f6635bacf3 100644 --- a/ios/RNSScreenStackComponentView.mm +++ b/ios/RNSScreenStackComponentView.mm @@ -1,5 +1,5 @@ #import "RNSScreenStackComponentView.h" -#import "RNSScreenComponentView.h" +#import "RNSScreen.h" #import "RNSScreenStackAnimator.h" #import "RNSScreenStackHeaderConfigComponentView.h" #import "RNSScreenWindowTraits.h" @@ -49,7 +49,7 @@ @implementation RNSPanGestureRecognizerF @implementation RNSScreenStackComponentView { UINavigationController *_controller; - NSMutableArray *_reactSubviews; + NSMutableArray *_reactSubviews; BOOL _invalidated; UIView *_snapshot; BOOL _isFullWidthSwiping; @@ -76,7 +76,9 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { - if (![childComponentView isKindOfClass:[RNSScreenComponentView class]]) { + // TODO: Remove this if def when merging with RNSScreenStack +#ifdef RN_FABRIC_ENABLED + if (![childComponentView isKindOfClass:[RNSScreenView class]]) { RCTLogError(@"ScreenStack only accepts children of type Screen"); return; } @@ -89,16 +91,19 @@ - (void)mountChildComponentView:(UIView *)childCompone @(index), @([childComponentView.superview tag])); - [_reactSubviews insertObject:(RNSScreenComponentView *)childComponentView atIndex:index]; - ((RNSScreenComponentView *)childComponentView).reactSuperview = self; + [_reactSubviews insertObject:(RNSScreenView *)childComponentView atIndex:index]; + ((RNSScreenView *)childComponentView).reactSuperview = self; dispatch_async(dispatch_get_main_queue(), ^{ [self maybeAddToParentAndUpdateContainer]; }); +#endif } - (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { - RNSScreenComponentView *screenChildComponent = (RNSScreenComponentView *)childComponentView; + // TODO: Remove this if def when merging with RNSScreenStack +#ifdef RN_FABRIC_ENABLED + RNSScreenView *screenChildComponent = (RNSScreenView *)childComponentView; // We should only do a snapshot of a screen that is on the top if (screenChildComponent == _controller.topViewController.view) { [screenChildComponent.controller setViewToSnapshot:_snapshot]; @@ -124,6 +129,7 @@ - (void)unmountChildComponentView:(UIView *)childCompo dispatch_async(dispatch_get_main_queue(), ^{ [self maybeAddToParentAndUpdateContainer]; }); +#endif } - (void)takeSnapshot @@ -152,12 +158,16 @@ - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { + // TODO: Remove this if def when merging with RNSScreenStack +#ifdef RN_FABRIC_ENABLED + UIView *view = viewController.view; - if ([view isKindOfClass:RNSScreenComponentView.class]) { + if ([view isKindOfClass:RNSScreenView.class]) { RNSScreenStackHeaderConfigComponentView *config = - (RNSScreenStackHeaderConfigComponentView *)((RNSScreenComponentView *)view).config; + (RNSScreenStackHeaderConfigComponentView *)((RNSScreenView *)view).config; [RNSScreenStackHeaderConfigComponentView willShowViewController:viewController animated:animated withConfig:config]; } +#endif } - (void)maybeAddToParentAndUpdateContainer @@ -208,7 +218,7 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio // We don't directly set presentation delegate but instead rely on the ScreenView's delegate to // forward certain calls to the container (Stack). UIView *screenView = presentationController.presentedViewController.view; - if ([screenView isKindOfClass:[RNSScreenComponentView class]]) { + if ([screenView isKindOfClass:[RNSScreenView class]]) { // we trigger the update of status bar's appearance here because there is no other lifecycle method // that can handle it when dismissing a modal, the same for orientation [RNSScreenWindowTraits updateWindowTraits]; @@ -233,6 +243,9 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio - (void)setPushViewControllers:(NSArray *)controllers { + // TODO: Remove this if def when merging with RNSScreenStack +#ifdef RN_FABRIC_ENABLED + // when there is no change we return immediately if ([_controller.viewControllers isEqualToArray:controllers]) { return; @@ -273,7 +286,7 @@ - (void)setPushViewControllers:(NSArray *)controllers // instance. This is a workaround for header height adjustment bug (see comment // in the init function). Here, we need to detect if the initial empty // controller is still there - BOOL firstTimePush = ![previousTop isKindOfClass:[RNSScreenController class]]; + BOOL firstTimePush = ![previousTop isKindOfClass:[RNSScreen class]]; if (firstTimePush) { // nothing pushed yet @@ -284,7 +297,7 @@ - (void)setPushViewControllers:(NSArray *)controllers // was called, so we check the animation if (![_controller.viewControllers containsObject:top]) { // setting new controllers with animation does `push` animation by default - auto screenController = (RNSScreenController *)top; + auto screenController = (RNSScreen *)top; [screenController resetViewToScreen]; [_controller setViewControllers:controllers animated:YES]; } else { @@ -303,7 +316,7 @@ - (void)setPushViewControllers:(NSArray *)controllers NSMutableArray *newControllers = [NSMutableArray arrayWithArray:controllers]; [newControllers removeLastObject]; [_controller setViewControllers:newControllers animated:NO]; - auto screenController = (RNSScreenController *)top; + auto screenController = (RNSScreen *)top; [screenController resetViewToScreen]; [_controller pushViewController:top animated:YES]; } else { @@ -315,6 +328,7 @@ - (void)setPushViewControllers:(NSArray *)controllers // change wasn't on the top of the stack. We don't need animation. [_controller setViewControllers:controllers animated:NO]; } +#endif } - (void)setModalViewControllers:(NSArray *)controllers @@ -413,8 +427,8 @@ - (void)setModalViewControllers:(NSArray *)controllers } #endif - BOOL shouldAnimate = lastModal && [next isKindOfClass:[RNSScreenController class]] && - ((RNSScreenComponentView *)next.view).stackAnimation != RNSScreenStackAnimationNone; + BOOL shouldAnimate = lastModal && [next isKindOfClass:[RNSScreen class]] && + ((RNSScreenView *)next.view).stackAnimation != RNSScreenStackAnimationNone; // if you want to present another modal quick enough after dismissing the previous one, // it will result in wrong changeRootController, see repro in @@ -440,8 +454,8 @@ - (void)setModalViewControllers:(NSArray *)controllers if (changeRootController.presentedViewController != nil && [_presentedModals containsObject:changeRootController.presentedViewController]) { BOOL shouldAnimate = changeRootIndex == controllers.count && - [changeRootController.presentedViewController isKindOfClass:[RNSScreenController class]] && - ((RNSScreenComponentView *)changeRootController.presentedViewController.view).stackAnimation != + [changeRootController.presentedViewController isKindOfClass:[RNSScreen class]] && + ((RNSScreenView *)changeRootController.presentedViewController.view).stackAnimation != RNSScreenStackAnimationNone; [changeRootController dismissViewControllerAnimated:shouldAnimate completion:finish]; } else { @@ -453,7 +467,7 @@ - (void)updateContainer { NSMutableArray *pushControllers = [NSMutableArray new]; NSMutableArray *modalControllers = [NSMutableArray new]; - for (RNSScreenComponentView *screen in _reactSubviews) { + for (RNSScreenView *screen in _reactSubviews) { if (screen.controller != nil) { if (pushControllers.count == 0) { // first screen on the list needs to be places as "push controller" @@ -480,8 +494,11 @@ - (void)layoutSubviews - (void)dismissOnReload { - auto screenController = (RNSScreenController *)_controller.topViewController; + // TODO: Remove this ifdef when merging with RNSScreenStack +#ifdef RN_FABRIC_ENABLED + auto screenController = (RNSScreen *)_controller.topViewController; [screenController resetViewToScreen]; +#endif } #pragma mark - methods connected to transitioning @@ -526,9 +543,9 @@ - (void)cancelTouchesInParent - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { - RNSScreenComponentView *topScreen = (RNSScreenComponentView *)_controller.viewControllers.lastObject.view; + RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view; - if (![topScreen isKindOfClass:[RNSScreenComponentView class]] || !topScreen.gestureEnabled || + if (![topScreen isKindOfClass:[RNSScreenView class]] || !topScreen.gestureEnabled || _controller.viewControllers.count < 2) { return NO; } @@ -587,7 +604,7 @@ - (void)setupGestureHandlers - (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer { - RNSScreenComponentView *topScreen = (RNSScreenComponentView *)_controller.viewControllers.lastObject.view; + RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view; float translation; float velocity; diff --git a/ios/RNSScreenStackHeaderConfigComponentView.h b/ios/RNSScreenStackHeaderConfigComponentView.h index 7fd944f643..390023adc8 100644 --- a/ios/RNSScreenStackHeaderConfigComponentView.h +++ b/ios/RNSScreenStackHeaderConfigComponentView.h @@ -2,12 +2,12 @@ #import -#import "RNSScreenComponentView.h" +#import "RNSScreen.h" #import "RNSScreenStackHeaderSubviewComponentView.h" @interface RNSScreenStackHeaderConfigComponentView : RCTViewComponentView -@property (nonatomic, weak) RNSScreenComponentView *screenView; +@property (nonatomic, weak) RNSScreenView *screenView; @property (nonatomic) NSMutableArray *reactSubviews; // Properties from props From 9f78cc080c425c4de9bd7ded2db968dcc2a85f20 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 14 Apr 2022 10:21:11 +0200 Subject: [PATCH 004/156] chore: update Cocoapods to .3 --- FabricExample/ios/Podfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FabricExample/ios/Podfile.lock b/FabricExample/ios/Podfile.lock index 9d3c7b46ed..3a247691e4 100644 --- a/FabricExample/ios/Podfile.lock +++ b/FabricExample/ios/Podfile.lock @@ -955,11 +955,11 @@ SPEC CHECKSUMS: React-rncore: f16be923fa7927977764ae31c65996f538b7e3b9 React-runtimeexecutor: 482f9d03c0764d4ae3fdf4687f6c975556bf71a2 ReactCommon: e23be08d1b21d8ab0dff24ce1afbe57942e9090f - RNScreens: b29ddf58060cdb2a274a044318a8c78b555f7860 + RNScreens: 2db1ede02cf20c64703931bc41c1ffe360377bfd SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 Yoga: d473a4284ea9eae9e312b38b8a62d9dedc4dd2f0 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a PODFILE CHECKSUM: d1692aab6ddf32b03dc03304e2dc04073ec65f35 -COCOAPODS: 1.11.2 +COCOAPODS: 1.11.3 From 9b183753121323b7031be5d9b4ed307c04d955af Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 14 Apr 2022 12:22:28 +0200 Subject: [PATCH 005/156] fix: type in RNSScreen.mm --- ios/RNSScreen.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index a2e65881be..a3ba3f2528 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -50,7 +50,7 @@ @implementation RNSScreenView { #endif } -#if RN_FABRIC_ENABLED +#ifdef RN_FABRIC_ENABLED - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { From 4a1c31515d688c39b4ea1dc6708d742cd3488212 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 14 Apr 2022 13:18:26 +0200 Subject: [PATCH 006/156] fix: add missing space to compiler flags in RNScreens.podspec It caused RN_FABRIC_ENABLED flag to be invalid (as it merged with previous flag from the list...) --- RNScreens.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RNScreens.podspec b/RNScreens.podspec index b224c31341..fd93a55dcb 100644 --- a/RNScreens.podspec +++ b/RNScreens.podspec @@ -29,7 +29,7 @@ Pod::Spec.new do |s| "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", } s.platforms = { ios: '11.0', tvos: '11.0' } - s.compiler_flags = folly_compiler_flags + '-DRN_FABRIC_ENABLED' + s.compiler_flags = folly_compiler_flags + ' -DRN_FABRIC_ENABLED' s.source_files = 'ios/**/*.{h,m,mm,cpp}' s.requires_arc = true From 76efc1915d7e1c0b15787f02b0d329af38b83023 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 12:06:31 +0200 Subject: [PATCH 007/156] refact: rename all source .m files to .mm Otherwise C++ standard headers are not visible from .m files -> project fails to build. e.g. Whem=n A.m includes B.h & B.h imports memory header: "#include " -- memory header is not visible & compilation fails --- ios/{RNSFullWindowOverlay.m => RNSFullWindowOverlay.mm} | 0 ios/{RNSScreenContainer.m => RNSScreenContainer.mm} | 0 ...creenNavigationContainer.m => RNSScreenNavigationContainer.mm} | 0 ios/{RNSScreenStack.m => RNSScreenStack.mm} | 0 ios/{RNSScreenStackAnimator.m => RNSScreenStackAnimator.mm} | 0 ...RNSScreenStackHeaderConfig.m => RNSScreenStackHeaderConfig.mm} | 0 ios/{RNSScreenWindowTraits.m => RNSScreenWindowTraits.mm} | 0 ios/{RNSSearchBar.m => RNSSearchBar.mm} | 0 ...UIViewController+RNScreens.m => UIViewController+RNScreens.mm} | 0 ios/{UIWindow+RNScreens.m => UIWindow+RNScreens.mm} | 0 10 files changed, 0 insertions(+), 0 deletions(-) rename ios/{RNSFullWindowOverlay.m => RNSFullWindowOverlay.mm} (100%) rename ios/{RNSScreenContainer.m => RNSScreenContainer.mm} (100%) rename ios/{RNSScreenNavigationContainer.m => RNSScreenNavigationContainer.mm} (100%) rename ios/{RNSScreenStack.m => RNSScreenStack.mm} (100%) rename ios/{RNSScreenStackAnimator.m => RNSScreenStackAnimator.mm} (100%) rename ios/{RNSScreenStackHeaderConfig.m => RNSScreenStackHeaderConfig.mm} (100%) rename ios/{RNSScreenWindowTraits.m => RNSScreenWindowTraits.mm} (100%) rename ios/{RNSSearchBar.m => RNSSearchBar.mm} (100%) rename ios/{UIViewController+RNScreens.m => UIViewController+RNScreens.mm} (100%) rename ios/{UIWindow+RNScreens.m => UIWindow+RNScreens.mm} (100%) diff --git a/ios/RNSFullWindowOverlay.m b/ios/RNSFullWindowOverlay.mm similarity index 100% rename from ios/RNSFullWindowOverlay.m rename to ios/RNSFullWindowOverlay.mm diff --git a/ios/RNSScreenContainer.m b/ios/RNSScreenContainer.mm similarity index 100% rename from ios/RNSScreenContainer.m rename to ios/RNSScreenContainer.mm diff --git a/ios/RNSScreenNavigationContainer.m b/ios/RNSScreenNavigationContainer.mm similarity index 100% rename from ios/RNSScreenNavigationContainer.m rename to ios/RNSScreenNavigationContainer.mm diff --git a/ios/RNSScreenStack.m b/ios/RNSScreenStack.mm similarity index 100% rename from ios/RNSScreenStack.m rename to ios/RNSScreenStack.mm diff --git a/ios/RNSScreenStackAnimator.m b/ios/RNSScreenStackAnimator.mm similarity index 100% rename from ios/RNSScreenStackAnimator.m rename to ios/RNSScreenStackAnimator.mm diff --git a/ios/RNSScreenStackHeaderConfig.m b/ios/RNSScreenStackHeaderConfig.mm similarity index 100% rename from ios/RNSScreenStackHeaderConfig.m rename to ios/RNSScreenStackHeaderConfig.mm diff --git a/ios/RNSScreenWindowTraits.m b/ios/RNSScreenWindowTraits.mm similarity index 100% rename from ios/RNSScreenWindowTraits.m rename to ios/RNSScreenWindowTraits.mm diff --git a/ios/RNSSearchBar.m b/ios/RNSSearchBar.mm similarity index 100% rename from ios/RNSSearchBar.m rename to ios/RNSSearchBar.mm diff --git a/ios/UIViewController+RNScreens.m b/ios/UIViewController+RNScreens.mm similarity index 100% rename from ios/UIViewController+RNScreens.m rename to ios/UIViewController+RNScreens.mm diff --git a/ios/UIWindow+RNScreens.m b/ios/UIWindow+RNScreens.mm similarity index 100% rename from ios/UIWindow+RNScreens.m rename to ios/UIWindow+RNScreens.mm From 947ac3d315eab3f090168872213e705879b09b20 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 12:10:01 +0200 Subject: [PATCH 008/156] chore: update FabricExample's Podfile.lock --- FabricExample/ios/Podfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FabricExample/ios/Podfile.lock b/FabricExample/ios/Podfile.lock index 3a247691e4..5c225fd1c0 100644 --- a/FabricExample/ios/Podfile.lock +++ b/FabricExample/ios/Podfile.lock @@ -955,7 +955,7 @@ SPEC CHECKSUMS: React-rncore: f16be923fa7927977764ae31c65996f538b7e3b9 React-runtimeexecutor: 482f9d03c0764d4ae3fdf4687f6c975556bf71a2 ReactCommon: e23be08d1b21d8ab0dff24ce1afbe57942e9090f - RNScreens: 2db1ede02cf20c64703931bc41c1ffe360377bfd + RNScreens: 592316e0744de3b640e90c335a45aad13088381a SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 Yoga: d473a4284ea9eae9e312b38b8a62d9dedc4dd2f0 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a From c2e020d0fb6d2e27b14dd13cb76c0945909a7fd3 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 12:18:37 +0200 Subject: [PATCH 009/156] fix: move reactSetFrame: method to Paper specific section --- ios/RNSScreen.mm | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index a3ba3f2528..2ee0402c15 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -92,20 +92,6 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge } #endif -- (void)reactSetFrame:(CGRect)frame -{ - _reactFrame = frame; - UIViewController *parentVC = self.reactViewController.parentViewController; - if (parentVC != nil && ![parentVC isKindOfClass:[RNScreensNavigationController class]]) { - [super reactSetFrame:frame]; - } - // when screen is mounted under RNScreensNavigationController it's size is controller - // by the navigation controller itself. That is, it is set to fill space of - // the controller. In that case we ignore react layout system from managing - // the screen dimensions and we wait for the screen VC to update and then we - // pass the dimensions to ui view manager to take into account when laying out - // subviews -} - (UIViewController *)reactViewController { @@ -588,6 +574,22 @@ - (void)updateState:(facebook::react::State::Shared const &)state #pragma mark - Paper specific #else + +- (void)reactSetFrame:(CGRect)frame +{ + _reactFrame = frame; + UIViewController *parentVC = self.reactViewController.parentViewController; + if (parentVC != nil && ![parentVC isKindOfClass:[RNScreensNavigationController class]]) { + [super reactSetFrame:frame]; + } + // when screen is mounted under RNScreensNavigationController it's size is controller + // by the navigation controller itself. That is, it is set to fill space of + // the controller. In that case we ignore react layout system from managing + // the screen dimensions and we wait for the screen VC to update and then we + // pass the dimensions to ui view manager to take into account when laying out + // subviews +} + - (void)presentationControllerWillDismiss:(UIPresentationController *)presentationController { // We need to call both "cancel" and "reset" here because RN's gesture recognizer From f0c88c26ae75ca2e5db1f119051dd5c5e5357386 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 12:20:22 +0200 Subject: [PATCH 010/156] fix: fix typo in ifdef directive --- ios/RNSScreen.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 2ee0402c15..ca7b23558a 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -100,7 +100,7 @@ - (UIViewController *)reactViewController - (void)updateBounds { -#ifdef RN_FABRIC_ENDABLED +#ifdef RN_FABRIC_ENABLED if (_state != nullptr) { auto newState = facebook::react::RNSScreenState{RCTSizeFromCGSize(self.bounds.size)}; _state->updateState(std::move(newState)); From b37a60a7cf331f3dac9ac5845ba29be58e0bd4f3 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 12:22:21 +0200 Subject: [PATCH 011/156] fix: temporary: move setActivityStateOrNil & setPointerEvents methods to paper specific section --- ios/RNSScreen.mm | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index ca7b23558a..f8c588af0b 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -112,24 +112,6 @@ - (void)updateBounds #endif } -// Nil will be provided when activityState is set as an animated value and we change -// it from JS to be a plain value (non animated). -// In case when nil is received, we want to ignore such value and not make -// any updates as the actual non-nil value will follow immediately. -- (void)setActivityStateOrNil:(NSNumber *)activityStateOrNil -{ - int activityState = [activityStateOrNil intValue]; - if (activityStateOrNil != nil && activityState != _activityState) { - _activityState = activityState; - [_reactSuperview markChildUpdated]; - } -} - -- (void)setPointerEvents:(RCTPointerEvents)pointerEvents -{ - // pointer events settings are managed by the parent screen container, we ignore - // any attempt of setting that via React props -} - (void)setStackPresentation:(RNSScreenStackPresentation)stackPresentation { @@ -575,6 +557,25 @@ - (void)updateState:(facebook::react::State::Shared const &)state #pragma mark - Paper specific #else +// Nil will be provided when activityState is set as an animated value and we change +// it from JS to be a plain value (non animated). +// In case when nil is received, we want to ignore such value and not make +// any updates as the actual non-nil value will follow immediately. +- (void)setActivityStateOrNil:(NSNumber *)activityStateOrNil +{ + int activityState = [activityStateOrNil intValue]; + if (activityStateOrNil != nil && activityState != _activityState) { + _activityState = activityState; + [_reactSuperview markChildUpdated] + } +} + +- (void)setPointerEvents:(RCTPointerEvents)pointerEvents +{ + // pointer events settings are managed by the parent screen container, we ignore + // any attempt of setting that via React props +} + - (void)reactSetFrame:(CGRect)frame { _reactFrame = frame; From 6825875730eea9ebf6c6942d1cd0ef677c62a43e Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 12:27:28 +0200 Subject: [PATCH 012/156] fix: add missing replaceAnimation prop (NOT TESTED) 1. move the prop to implemented section in JS 2. move the prop to "common" section in RNSScreenView interface --- ios/RNSScreen.h | 2 +- src/fabric/ScreenNativeComponent.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/RNSScreen.h b/ios/RNSScreen.h index 4c59f9a334..ee288a03fb 100644 --- a/ios/RNSScreen.h +++ b/ios/RNSScreen.h @@ -58,6 +58,7 @@ @property (nonatomic) RNSScreenStackAnimation stackAnimation; @property (nonatomic) RNSScreenStackPresentation stackPresentation; @property (nonatomic) RNSScreenSwipeDirection swipeDirection; +@property (nonatomic) RNSScreenReplaceAnimation replaceAnimation; @property (nonatomic, retain) NSNumber *transitionDuration; #if !TARGET_OS_TV @@ -85,7 +86,6 @@ @property (nonatomic, retain) UIViewController *controller; @property (nonatomic, readonly) BOOL dismissed; @property (nonatomic) int activityState; -@property (nonatomic) RNSScreenReplaceAnimation replaceAnimation; @property (nonatomic) BOOL preventNativeDismiss; @property (nonatomic) BOOL customAnimationOnSwipe; @property (nonatomic, copy) NSDictionary *gestureResponseDistance; diff --git a/src/fabric/ScreenNativeComponent.js b/src/fabric/ScreenNativeComponent.js index 86cf53b3c2..6e9b416961 100644 --- a/src/fabric/ScreenNativeComponent.js +++ b/src/fabric/ScreenNativeComponent.js @@ -59,8 +59,8 @@ export type NativeProps = $ReadOnly<{| stackPresentation?: WithDefault, stackAnimation?: WithDefault, transitionDuration?: WithDefault, - // TODO: implement these props on iOS replaceAnimation?: WithDefault, + // TODO: implement these props on iOS navigationBarColor?: ColorValue, navigationBarHidden?: boolean, nativeBackButtonDismissalEnabled?: boolean, From ce01586d32448b51052c3f7a0fa5f5055ffa083e Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 12:47:38 +0200 Subject: [PATCH 013/156] fix: move notifyFinishTransitioning method to Paper specific section --- ios/RNSScreen.mm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index f8c588af0b..9ff1f7a405 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -259,11 +259,6 @@ - (void)addSubview:(UIView *)view } } -- (void)notifyFinishTransitioning -{ - [_controller notifyFinishTransitioning]; -} - - (void)notifyDismissedWithCount:(int)dismissCount { #ifdef RN_FABRIC_ENABLED @@ -557,6 +552,11 @@ - (void)updateState:(facebook::react::State::Shared const &)state #pragma mark - Paper specific #else +- (void)notifyFinishTransitioning +{ + [_controller notifyFinishTransitioning]; +} + // Nil will be provided when activityState is set as an animated value and we change // it from JS to be a plain value (non animated). // In case when nil is received, we want to ignore such value and not make From 8a1525c20f6b9f39568d16ed7dadc711d598577e Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 12:51:39 +0200 Subject: [PATCH 014/156] fix: move notifyDismissCancelledWithDismissCount: method to Paper specific section --- ios/RNSScreen.mm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 9ff1f7a405..24e8280655 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -352,13 +352,6 @@ - (void)notifyDisappear #endif } -- (void)notifyDismissCancelledWithDismissCount:(int)dismissCount -{ - if (self.onNativeDismissCancelled) { - self.onNativeDismissCancelled(@{@"dismissCount" : @(dismissCount)}); - } -} - - (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingForward:(BOOL)goingForward { if (self.onTransitionProgress) { @@ -557,6 +550,13 @@ - (void)notifyFinishTransitioning [_controller notifyFinishTransitioning]; } +- (void)notifyDismissCancelledWithDismissCount:(int)dismissCount +{ + if (self.onNativeDismissCancelled) { + self.onNativeDismissCancelled(@{@"dismissCount" : @(dismissCount)}); + } +} + // Nil will be provided when activityState is set as an animated value and we change // it from JS to be a plain value (non animated). // In case when nil is received, we want to ignore such value and not make From 249d6753802bee96d4df5765238bfdad42229fd4 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 12:53:01 +0200 Subject: [PATCH 015/156] fix: move notifyTransitionProgress:closing:goingForward: method to Paper specific section Aim: to ake project compile --- ios/RNSScreen.mm | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 24e8280655..a3d1fff373 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -352,17 +352,6 @@ - (void)notifyDisappear #endif } -- (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingForward:(BOOL)goingForward -{ - if (self.onTransitionProgress) { - self.onTransitionProgress(@{ - @"progress" : @(progress), - @"closing" : @(closing ? 1 : 0), - @"goingForward" : @(goingForward ? 1 : 0), - }); - } -} - - (BOOL)isMountedUnderScreenOrReactRoot { #ifdef RN_FABRIC_ENABLED @@ -557,6 +546,17 @@ - (void)notifyDismissCancelledWithDismissCount:(int)dismissCount } } +- (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingForward:(BOOL)goingForward +{ + if (self.onTransitionProgress) { + self.onTransitionProgress(@{ + @"progress" : @(progress), + @"closing" : @(closing ? 1 : 0), + @"goingForward" : @(goingForward ? 1 : 0), + }); + } +} + // Nil will be provided when activityState is set as an animated value and we change // it from JS to be a plain value (non animated). // In case when nil is received, we want to ignore such value and not make From 5e89e5b3d2540a193eb253784f8992aa8709101f Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 12:58:00 +0200 Subject: [PATCH 016/156] fix: remove duplication of prop setting most likely some kind of merging artifact --- ios/RNSScreen.mm | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index a3d1fff373..323361f555 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -488,37 +488,6 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props [self logPropNotAvailable:@"statusBarTranslucent"]; } - [self setFullScreenSwipeEnabled:newScreenProps.fullScreenSwipeEnabled]; - - [self setGestureEnabled:newScreenProps.gestureEnabled]; - - if (newScreenProps.statusBarHidden != oldScreenProps.statusBarHidden) { - [self setStatusBarHidden:newScreenProps.statusBarHidden]; - } - - if (newScreenProps.statusBarStyle != oldScreenProps.statusBarStyle) { - [self setStatusBarStyle:[RCTConvert RNSStatusBarStyle:[self stringToPropValue:newScreenProps.statusBarStyle]]]; - } - - if (newScreenProps.statusBarAnimation != oldScreenProps.statusBarAnimation) { - [self setStatusBarAnimation:[RCTConvert - UIStatusBarAnimation:[self stringToPropValue:newScreenProps.statusBarAnimation]]]; - } - - if (newScreenProps.screenOrientation != oldScreenProps.screenOrientation) { - [self - setScreenOrientation:[RCTConvert - UIInterfaceOrientationMask:[self stringToPropValue:newScreenProps.screenOrientation]]]; - } - - if (newScreenProps.statusBarColor) { - [self logPropNotAvailable:@"statusBarColor"]; - } - - if (newScreenProps.statusBarTranslucent) { - [self logPropNotAvailable:@"statusBarTranslucent"]; - } - [super updateProps:props oldProps:oldProps]; _fullScreenSwipeEnabled = newScreenProps.fullScreenSwipeEnabled; From d028f87ce4e3691a4d7294235cfe6d3961ebb5e9 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 12:58:42 +0200 Subject: [PATCH 017/156] chore: change handling of unsupported props to noop --- ios/RNSScreen.mm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 323361f555..c689288632 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -480,14 +480,6 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props [self setStackAnimation:[RNSConvert RNSScreenStackAnimationFromCppEquivalent:newScreenProps.stackAnimation]]; } - if (newScreenProps.statusBarColor) { - [self logPropNotAvailable:@"statusBarColor"]; - } - - if (newScreenProps.statusBarTranslucent) { - [self logPropNotAvailable:@"statusBarTranslucent"]; - } - [super updateProps:props oldProps:oldProps]; _fullScreenSwipeEnabled = newScreenProps.fullScreenSwipeEnabled; From ebdbafa3ad92e7dc63819aed1eb50b82410baa9e Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 13:04:23 +0200 Subject: [PATCH 018/156] fix: move RNSScreenManager impl & def under !RN_FABRIC_ENABLED condition --- ios/RNSScreen.h | 8 ++++---- ios/RNSScreen.mm | 9 ++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/ios/RNSScreen.h b/ios/RNSScreen.h index ee288a03fb..940cad393a 100644 --- a/ios/RNSScreen.h +++ b/ios/RNSScreen.h @@ -36,10 +36,6 @@ @end -@interface RNSScreenManager : RCTViewManager - -@end - #ifdef RN_FABRIC_ENABLED #define BASE_VIEW RCTViewComponentView #else @@ -110,5 +106,9 @@ #else @interface UIView (RNSScreen) - (UIViewController *)parentViewController; +@end + +@interface RNSScreenManager : RCTViewManager + @end #endif diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index c689288632..5f1d1d289c 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -92,7 +92,6 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge } #endif - - (UIViewController *)reactViewController { return _controller; @@ -112,7 +111,6 @@ - (void)updateBounds #endif } - - (void)setStackPresentation:(RNSScreenStackPresentation)stackPresentation { switch (stackPresentation) { @@ -1199,8 +1197,11 @@ - (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingFor @end -#endif +#endif // RN_FABRIC_ENABLED +#ifdef RN_FABRIC_ENABLED + +#else @implementation RNSScreenManager RCT_EXPORT_MODULE() @@ -1241,6 +1242,8 @@ - (UIView *)view @end +#endif // RN_FABRIC_ENABLED + @implementation RCTConvert (RNSScreen) RCT_ENUM_CONVERTER( From cfd3842c092f4ffd77db2d1cad0b44d25aaafb2b Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 13:11:33 +0200 Subject: [PATCH 019/156] fix: remove duplicated prop update in updateProps method most likely some kind of merge artifact --- ios/RNSScreen.mm | 3 --- 1 file changed, 3 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 5f1d1d289c..754a800d2b 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -479,9 +479,6 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props } [super updateProps:props oldProps:oldProps]; - - _fullScreenSwipeEnabled = newScreenProps.fullScreenSwipeEnabled; - _gestureEnabled = newScreenProps.gestureEnabled; } - (void)updateState:(facebook::react::State::Shared const &)state From 40d438a32f85934f73cc36b2aeb9af71a6cde203 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 15 Apr 2022 13:20:15 +0200 Subject: [PATCH 020/156] fix: temporary: exclude usages of customAnimationOnSwipe from Fabric temporary solution until customAnimationOnSwipe is not added to RNSScreenView on Fabric --- ios/RNSScreenStackAnimator.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ios/RNSScreenStackAnimator.mm b/ios/RNSScreenStackAnimator.mm index efc10ff8c5..4b5f5cab41 100644 --- a/ios/RNSScreenStackAnimator.mm +++ b/ios/RNSScreenStackAnimator.mm @@ -66,12 +66,15 @@ - (void)animateTransition:(id)transitionCo if (screen != nil) { if (screen.fullScreenSwipeEnabled && transitionContext.isInteractive) { // we are swiping with full width gesture +#ifndef RN_FABRIC_ENABLED if (screen.customAnimationOnSwipe) { [self animateTransitionWithStackAnimation:screen.stackAnimation transitionContext:transitionContext toVC:toViewController fromVC:fromViewController]; - } else { + } else +#endif + { // we have to provide an animation when swiping, otherwise the screen will be popped immediately, // so in case of no custom animation on swipe set, we provide the one closest to the default [self animateSimplePushWithTransitionContext:transitionContext toVC:toViewController fromVC:fromViewController]; From e79ae5f49288eb79d943285d2133dcde306604b0 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 09:15:23 +0200 Subject: [PATCH 021/156] fix: make the project compile these directives should be removed once implementations ale fully merged --- ios/RNSScreenContainer.mm | 4 ++++ ios/RNSScreenNavigationContainer.mm | 2 ++ ios/RNSScreenStack.mm | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/ios/RNSScreenContainer.mm b/ios/RNSScreenContainer.mm index ffdf066412..eff360572d 100644 --- a/ios/RNSScreenContainer.mm +++ b/ios/RNSScreenContainer.mm @@ -32,12 +32,14 @@ - (UIViewController *)childViewControllerForHomeIndicatorAutoHidden - (UIViewController *)findActiveChildVC { +#ifndef RN_FABRIC_ENABLED for (UIViewController *childVC in self.childViewControllers) { if ([childVC isKindOfClass:[RNSScreen class]] && ((RNSScreenView *)((RNSScreen *)childVC.view)).activityState == RNSActivityStateOnTop) { return childVC; } } +#endif return [[self childViewControllers] lastObject]; } @@ -139,6 +141,7 @@ - (void)attachScreen:(RNSScreenView *)screen atIndex:(NSInteger)index - (void)updateContainer { +#ifndef RN_FABRIC_ENABLED BOOL screenRemoved = NO; // remove screens that are no longer active NSMutableSet *orphaned = [NSMutableSet setWithSet:_activeScreens]; @@ -188,6 +191,7 @@ - (void)updateContainer if (screenRemoved || screenAdded) { [self maybeDismissVC]; } +#endif } - (void)maybeDismissVC diff --git a/ios/RNSScreenNavigationContainer.mm b/ios/RNSScreenNavigationContainer.mm index 649e41b6d0..1d362d7535 100644 --- a/ios/RNSScreenNavigationContainer.mm +++ b/ios/RNSScreenNavigationContainer.mm @@ -17,6 +17,7 @@ - (void)setupController - (void)updateContainer { +#ifndef RN_FABRIC_ENABLED for (RNSScreenView *screen in self.reactSubviews) { if (screen.activityState == RNSActivityStateOnTop) { // there should never be more than one screen with `RNSActivityStateOnTop` @@ -27,6 +28,7 @@ - (void)updateContainer } [self maybeDismissVC]; +#endif } @end diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 06d13f04a9..e1e3b62834 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -485,6 +485,7 @@ - (void)setPushViewControllers:(NSArray *)controllers - (void)updateContainer { +#ifndef RN_FABRIC_ENABLED NSMutableArray *pushControllers = [NSMutableArray new]; NSMutableArray *modalControllers = [NSMutableArray new]; for (RNSScreenView *screen in _reactSubviews) { @@ -504,6 +505,7 @@ - (void)updateContainer [self setPushViewControllers:pushControllers]; [self setModalViewControllers:modalControllers]; +#endif } // By default, the header buttons that are not inside the native hit area @@ -571,6 +573,7 @@ - (void)dismissOnReload - (BOOL)isInGestureResponseDistance:(UIGestureRecognizer *)gestureRecognizer topScreen:(RNSScreenView *)topScreen { +#ifndef RN_FABRIC_ENABLED NSDictionary *gestureResponseDistanceValues = topScreen.gestureResponseDistance; float x = [gestureRecognizer locationInView:gestureRecognizer.view].x; float y = [gestureRecognizer locationInView:gestureRecognizer.view].y; @@ -584,6 +587,9 @@ - (BOOL)isInGestureResponseDistance:(UIGestureRecognizer *)gestureRecognizer top (gestureResponseDistanceValues[@"end"] && x > [gestureResponseDistanceValues[@"end"] floatValue]) || (gestureResponseDistanceValues[@"top"] && y < [gestureResponseDistanceValues[@"top"] floatValue]) || (gestureResponseDistanceValues[@"bottom"] && y > [gestureResponseDistanceValues[@"bottom"] floatValue])); +#else + return NO; +#endif } - (void)cancelTouchesInParent @@ -627,6 +633,7 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer return NO; } +#ifndef RN_FABRIC_ENABLED if (topScreen.customAnimationOnSwipe && [RNSScreenStackAnimator isCustomAnimation:topScreen.stackAnimation]) { if ([gestureRecognizer isKindOfClass:[RNSScreenEdgeGestureRecognizer class]]) { // if we do not set any explicit `semanticContentAttribute`, it is `UISemanticContentAttributeUnspecified` instead @@ -652,6 +659,18 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer [self cancelTouchesInParent]; return YES; } +#else + if ([gestureRecognizer isKindOfClass:[RNSScreenEdgeGestureRecognizer class]]) { + // it should only recognize with `customAnimationOnSwipe` set + return NO; + } else if ([gestureRecognizer isKindOfClass:[RNSPanGestureRecognizer class]]) { + // it should only recognize with `fullScreenSwipeEnabled` set + return NO; + } + [self cancelTouchesInParent]; + return _controller.viewControllers.count >= 2; +#endif + #endif } From a7e3012132f294b5fcb4cd06b69a6808c9970047 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:05 +0200 Subject: [PATCH 022/156] chore: merge ScreenStack headers --- ios/RNSScreenStack.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ios/RNSScreenStack.h b/ios/RNSScreenStack.h index a383cd2265..d340c3c4d5 100644 --- a/ios/RNSScreenStack.h +++ b/ios/RNSScreenStack.h @@ -1,5 +1,10 @@ +#ifdef RN_FABRIC_ENABLED +#import +#import +#else #import #import +#endif #import "RNSScreenContainer.h" @@ -7,15 +12,24 @@ @end -@interface RNSScreenStackView : UIView +@interface RNSScreenStackView : +#ifdef RN_FABRIC_ENABLED + RCTViewComponentView +#else + UIView +#endif +#ifndef RN_FABRIC_ENABLED @property (nonatomic, copy) RCTDirectEventBlock onFinishTransitioning; - (void)markChildUpdated; - (void)didUpdateChildren; +#endif @end +#ifndef RN_FABRIC_ENABLED @interface RNSScreenStackManager : RCTViewManager @end +#endif From 4ea96a79914d58f37f6cbd5a187117cf1de2d4d7 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:07 +0200 Subject: [PATCH 023/156] chore: merge imports in ScreenStack impls --- ios/RNSScreenStack.mm | 50 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index e1e3b62834..fac1e47935 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -1,8 +1,19 @@ -#import "RNSScreenStack.h" -#import "RNSScreen.h" -#import "RNSScreenStackAnimator.h" +#ifdef RN_FABRIC_ENABLED +#import "RNSScreenStackHeaderConfigComponentView.h" + +#import + +#import +#import +#import +#import +#import + +#import "RCTFabricComponentsPlugins.h" + +#import +#else #import "RNSScreenStackHeaderConfig.h" -#import "RNSScreenWindowTraits.h" #import #import @@ -10,12 +21,31 @@ #import #import #import +#endif // RN_FABRIC_ENABLED -@interface RNSScreenStackView () < +#import "RNSScreenStack.h" +#import "RNSScreen.h" +#import "RNSScreenStackAnimator.h" +#import "RNSScreenWindowTraits.h" + +@interface RNSScreenStackView () +#ifdef RN_FABRIC_ENABLED +< + UINavigationControllerDelegate, + UIAdaptivePresentationControllerDelegate, + UIGestureRecognizerDelegate, + UIViewControllerTransitioningDelegate, + RCTMountingTransactionObserving> { + BOOL _updateScheduled; +} +#else +< UINavigationControllerDelegate, UIAdaptivePresentationControllerDelegate, UIGestureRecognizerDelegate, UIViewControllerTransitioningDelegate> +#endif + @property (nonatomic) NSMutableArray *presentedModals; @property (nonatomic) BOOL updatingModals; @@ -71,12 +101,16 @@ @implementation RNSPanGestureRecognizer @implementation RNSScreenStackView { UINavigationController *_controller; NSMutableArray *_reactSubviews; - __weak RNSScreenStackManager *_manager; - BOOL _hasLayout; BOOL _invalidated; + BOOL _isFullWidthSwiping; UIPercentDrivenInteractiveTransition *_interactionController; +#ifdef RN_FABRIC_ENABLED + UIView *_snapshot; +#else + __weak RNSScreenStackManager *_manager; + BOOL _hasLayout; BOOL _updateScheduled; - BOOL _isFullWidthSwiping; +#endif } - (instancetype)initWithManager:(RNSScreenStackManager *)manager From f9160d4e06d625c1043521ac0b5346578328ca3c Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:09 +0200 Subject: [PATCH 024/156] chore: move initWithFrame: method & add sections --- ios/RNSScreenStack.mm | 48 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index fac1e47935..cc99e61c4e 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -113,6 +113,25 @@ @implementation RNSScreenStackView { #endif } +#ifdef RN_FABRIC_ENABLED +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + _reactSubviews = [NSMutableArray new]; + _presentedModals = [NSMutableArray new]; + _controller = [RNScreensNavigationController new]; + _controller.delegate = self; + [_controller setViewControllers:@[ [UIViewController new] ]]; +#if !TARGET_OS_TV + [self setupGestureHandlers]; +#endif + } + + return self; +} +#else - (instancetype)initWithManager:(RNSScreenStackManager *)manager { if (self = [super init]) { @@ -135,17 +154,24 @@ - (instancetype)initWithManager:(RNSScreenStackManager *)manager } return self; } +#endif // RN_FABRIC_ENABLED + +#pragma mark - Common -- (UIViewController *)reactViewController -{ - return _controller; -} - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated { UIView *view = viewController.view; + // TODO: Improve this merge when StackHeaderConfig is merged +#ifdef RN_FABRIC_ENABLED + if ([view isKindOfClass:RNSScreenView.class]) { + RNSScreenStackHeaderConfigComponentView *config = + (RNSScreenStackHeaderConfigComponentView *)((RNSScreenView *)view).config; + [RNSScreenStackHeaderConfigComponentView willShowViewController:viewController animated:animated withConfig:config]; + } +#else RNSScreenStackHeaderConfig *config = nil; for (UIView *subview in view.reactSubviews) { if ([subview isKindOfClass:[RNSScreenStackHeaderConfig class]]) { @@ -154,6 +180,7 @@ - (void)navigationController:(UINavigationController *)navigationController } } [RNSScreenStackHeaderConfig willShowViewController:viewController animated:animated withConfig:config]; +#endif } - (void)navigationController:(UINavigationController *)navigationController @@ -826,6 +853,19 @@ - (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer return _interactionController; } +#ifdef RN_FABRIC_ENABLED +#pragma mark - Fabric specific + +#else +#pragma mark - Paper specific + +- (UIViewController *)reactViewController +{ + return _controller; +} + +#endif + @end @implementation RNSScreenStackManager { From 22d0484fa84ab5c9012e1d69f60e45ac8c7c2674 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:11 +0200 Subject: [PATCH 025/156] chore: move navigationController:didShowViewController:animated method to Paper specific section This method is not present in RNSScreenStackComponentView, therefore I conclude it is not necessary at least for now --- ios/RNSScreenStack.mm | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index cc99e61c4e..9129fbe6bf 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -183,15 +183,6 @@ - (void)navigationController:(UINavigationController *)navigationController #endif } -- (void)navigationController:(UINavigationController *)navigationController - didShowViewController:(UIViewController *)viewController - animated:(BOOL)animated -{ - if (self.onFinishTransitioning) { - self.onFinishTransitioning(nil); - } - [RNSScreenWindowTraits updateWindowTraits]; -} - (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController { @@ -864,6 +855,17 @@ - (UIViewController *)reactViewController return _controller; } +- (void)navigationController:(UINavigationController *)navigationController + didShowViewController:(UIViewController *)viewController + animated:(BOOL)animated +{ + if (self.onFinishTransitioning) { + self.onFinishTransitioning(nil); + } + [RNSScreenWindowTraits updateWindowTraits]; +} + + #endif @end From 60b9d20e64bb481864a3d8d6136c80f2226aba63 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:13 +0200 Subject: [PATCH 026/156] chore: merge presentationControllerDidDismiss: method --- ios/RNSScreenStack.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 9129fbe6bf..8066467805 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -198,6 +198,8 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio // have tried to push another one during the transition _updatingModals = NO; [self updateContainer]; + // TODO: implement onFinishTransitioning on Fabric +#ifndef RN_FABRIC_ENABLED if (self.onFinishTransitioning) { // instead of directly triggering onFinishTransitioning this time we enqueue the event on the // main queue. We do that because onDismiss event is also enqueued and we want for the transition @@ -208,6 +210,7 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio } }); } +#endif } } From 30b3a1e0774b15b199d73534e9ec52c799d120d5 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:15 +0200 Subject: [PATCH 027/156] chore: move {mount,unmount}ChildComponentView:index: methods --- ios/RNSScreenStack.mm | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 8066467805..6e9822d7de 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -850,6 +850,57 @@ - (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer #ifdef RN_FABRIC_ENABLED #pragma mark - Fabric specific +- (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index +{ + if (![childComponentView isKindOfClass:[RNSScreenView class]]) { + RCTLogError(@"ScreenStack only accepts children of type Screen"); + return; + } + + RCTAssert( + childComponentView.reactSuperview == nil, + @"Attempt to mount already mounted component view. (parent: %@, child: %@, index: %@, existing parent: %@)", + self, + childComponentView, + @(index), + @([childComponentView.superview tag])); + + [_reactSubviews insertObject:(RNSScreenView *)childComponentView atIndex:index]; + ((RNSScreenView *)childComponentView).reactSuperview = self; + dispatch_async(dispatch_get_main_queue(), ^{ + [self maybeAddToParentAndUpdateContainer]; + }); +} + +- (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index +{ + RNSScreenView *screenChildComponent = (RNSScreenView *)childComponentView; + // We should only do a snapshot of a screen that is on the top + if (screenChildComponent == _controller.topViewController.view) { + [screenChildComponent.controller setViewToSnapshot:_snapshot]; + } + + RCTAssert( + screenChildComponent.reactSuperview == self, + @"Attempt to unmount a view which is mounted inside different view. (parent: %@, child: %@, index: %@)", + self, + screenChildComponent, + @(index)); + RCTAssert( + (_reactSubviews.count > index) && [_reactSubviews objectAtIndex:index] == childComponentView, + @"Attempt to unmount a view which has a different index. (parent: %@, child: %@, index: %@, actual index: %@, tag at index: %@)", + self, + screenChildComponent, + @(index), + @([_reactSubviews indexOfObject:screenChildComponent]), + @([[_reactSubviews objectAtIndex:index] tag])); + screenChildComponent.reactSuperview = nil; + [_reactSubviews removeObject:screenChildComponent]; + [screenChildComponent removeFromSuperview]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self maybeAddToParentAndUpdateContainer]; + }); +} #else #pragma mark - Paper specific From 384df76872ccbb03a39549c1e6fa9af0f19e7c6f Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:17 +0200 Subject: [PATCH 028/156] chore: move takeSnapshot method --- ios/RNSScreenStack.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 6e9822d7de..1b9b826503 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -901,6 +901,11 @@ - (void)unmountChildComponentView:(UIView *)childCompo [self maybeAddToParentAndUpdateContainer]; }); } + +- (void)takeSnapshot +{ + _snapshot = [_controller.topViewController.view snapshotViewAfterScreenUpdates:NO]; +} #else #pragma mark - Paper specific From 228aa31812c078a3da7dec5fdebd614f83454c4e Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:19 +0200 Subject: [PATCH 029/156] chore: merge didMoveToWindow methods --- ios/RNSScreenStack.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 1b9b826503..f42ea0174d 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -258,6 +258,11 @@ - (void)didUpdateReactSubviews - (void)didMoveToWindow { +#ifdef RN_FABRIC_ENABLED + [super didMoveToWindow]; + // for handling nested stacks + [self maybeAddToParentAndUpdateContainer]; +#else [super didMoveToWindow]; if (!_invalidated) { // We check whether the view has been invalidated before running side-effects in didMoveToWindow @@ -265,6 +270,7 @@ - (void)didMoveToWindow // to a window despite the fact it has been removed from the React Native view hierarchy. [self maybeAddToParentAndUpdateContainer]; } +#endif } - (void)maybeAddToParentAndUpdateContainer From bdd2c243e41fe04ae2e5219141fcddae3bdb0cc2 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:21 +0200 Subject: [PATCH 030/156] chore: move mountingTransactionWillMountWithMetadata: method to Fabric specific section --- ios/RNSScreenStack.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index f42ea0174d..04e1616fea 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -912,6 +912,12 @@ - (void)takeSnapshot { _snapshot = [_controller.topViewController.view snapshotViewAfterScreenUpdates:NO]; } + +- (void)mountingTransactionWillMountWithMetadata:(MountingTransactionMetadata const &)metadata +{ + [self takeSnapshot]; +} + #else #pragma mark - Paper specific From c2464675e732b66339affb0d89f94dce4ace8065 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:22 +0200 Subject: [PATCH 031/156] chore: merge maybeAddToParentAndUpdateContainer methods --- ios/RNSScreenStack.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 04e1616fea..b1362e463e 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -276,7 +276,11 @@ - (void)didMoveToWindow - (void)maybeAddToParentAndUpdateContainer { BOOL wasScreenMounted = _controller.parentViewController != nil; +#ifdef RN_FABRIC_ENABLED + BOOL isScreenReadyForShowing = self.window; +#else BOOL isScreenReadyForShowing = self.window && _hasLayout; +#endif if (!isScreenReadyForShowing && !wasScreenMounted) { // We wait with adding to parent controller until the stack is mounted and has its initial // layout done. From c2c625236fee704ad2cda729c8a01d87090caf31 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:24 +0200 Subject: [PATCH 032/156] chore: move markChildUpdated & didUpdateChildren methods to Paper specific section --- ios/RNSScreenStack.mm | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index b1362e463e..b1c7e7b669 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -158,7 +158,7 @@ - (instancetype)initWithManager:(RNSScreenStackManager *)manager #pragma mark - Common - +// done - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated @@ -183,7 +183,7 @@ - (void)navigationController:(UINavigationController *)navigationController #endif } - +// done - (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController { // We don't directly set presentation delegate but instead rely on the ScreenView's delegate to @@ -214,16 +214,6 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio } } -- (void)markChildUpdated -{ - // do nothing -} - -- (void)didUpdateChildren -{ - // do nothing -} - - (void)insertReactSubview:(RNSScreenView *)subview atIndex:(NSInteger)atIndex { if (![subview isKindOfClass:[RNSScreenView class]]) { @@ -925,6 +915,16 @@ - (void)mountingTransactionWillMountWithMetadata:(MountingTransactionMetadata co #else #pragma mark - Paper specific +- (void)markChildUpdated +{ + // do nothing +} + +- (void)didUpdateChildren +{ + // do nothing +} + - (UIViewController *)reactViewController { return _controller; From c91c43b3e3d61d0072439acdee56a96cea9cb790 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:26 +0200 Subject: [PATCH 033/156] chore: move insertReactSubview:atIndex: method to Paper specific section --- ios/RNSScreenStack.mm | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index b1c7e7b669..1eb450d3f8 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -214,16 +214,6 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio } } -- (void)insertReactSubview:(RNSScreenView *)subview atIndex:(NSInteger)atIndex -{ - if (![subview isKindOfClass:[RNSScreenView class]]) { - RCTLogError(@"ScreenStack only accepts children of type Screen"); - return; - } - subview.reactSuperview = self; - [_reactSubviews insertObject:subview atIndex:atIndex]; -} - - (void)removeReactSubview:(RNSScreenView *)subview { subview.reactSuperview = nil; @@ -940,6 +930,16 @@ - (void)navigationController:(UINavigationController *)navigationController [RNSScreenWindowTraits updateWindowTraits]; } +- (void)insertReactSubview:(RNSScreenView *)subview atIndex:(NSInteger)atIndex +{ + if (![subview isKindOfClass:[RNSScreenView class]]) { + RCTLogError(@"ScreenStack only accepts children of type Screen"); + return; + } + subview.reactSuperview = self; + [_reactSubviews insertObject:subview atIndex:atIndex]; +} + #endif From 16fe33de9509d368f61c5d2d8f75d0f4e9107776 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:28 +0200 Subject: [PATCH 034/156] chore: move removeReactSubview: method to paper specific section --- ios/RNSScreenStack.mm | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 1eb450d3f8..f3ffc1b878 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -214,12 +214,6 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio } } -- (void)removeReactSubview:(RNSScreenView *)subview -{ - subview.reactSuperview = nil; - [_reactSubviews removeObject:subview]; -} - - (NSArray *)reactSubviews { return _reactSubviews; @@ -941,6 +935,13 @@ - (void)insertReactSubview:(RNSScreenView *)subview atIndex:(NSInteger)atIndex } +- (void)removeReactSubview:(RNSScreenView *)subview +{ + subview.reactSuperview = nil; + [_reactSubviews removeObject:subview]; +} + + #endif @end From 906ce0dfc6d5f9606eaf2cdc345f995122700d18 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:30 +0200 Subject: [PATCH 035/156] chore: move didUpdateReactSubviews method to paper specific section --- ios/RNSScreenStack.mm | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index f3ffc1b878..783ab71805 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -214,22 +214,12 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio } } +// done - (NSArray *)reactSubviews { return _reactSubviews; } -- (void)didUpdateReactSubviews -{ - // we need to wait until children have their layout set. At this point they don't have the layout - // set yet, however the layout call is already enqueued on ui thread. Enqueuing update call on the - // ui queue will guarantee that the update will run after layout. - dispatch_async(dispatch_get_main_queue(), ^{ - self->_hasLayout = YES; - [self maybeAddToParentAndUpdateContainer]; - }); -} - - (void)didMoveToWindow { #ifdef RN_FABRIC_ENABLED @@ -934,13 +924,22 @@ - (void)insertReactSubview:(RNSScreenView *)subview atIndex:(NSInteger)atIndex [_reactSubviews insertObject:subview atIndex:atIndex]; } - - (void)removeReactSubview:(RNSScreenView *)subview { subview.reactSuperview = nil; [_reactSubviews removeObject:subview]; } +- (void)didUpdateReactSubviews +{ + // we need to wait until children have their layout set. At this point they don't have the layout + // set yet, however the layout call is already enqueued on ui thread. Enqueuing update call on the + // ui queue will guarantee that the update will run after layout. + dispatch_async(dispatch_get_main_queue(), ^{ + self->_hasLayout = YES; + [self maybeAddToParentAndUpdateContainer]; + }); +} #endif From 8c9585dbcb9535752110c6a94c821342757e1525 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:32 +0200 Subject: [PATCH 036/156] chore: merge reactAddControllerToClosestParent: methods --- ios/RNSScreenStack.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 783ab71805..9897b6d134 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -220,6 +220,7 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio return _reactSubviews; } +// done - (void)didMoveToWindow { #ifdef RN_FABRIC_ENABLED @@ -237,6 +238,7 @@ - (void)didMoveToWindow #endif } +// done - (void)maybeAddToParentAndUpdateContainer { BOOL wasScreenMounted = _controller.parentViewController != nil; @@ -283,7 +285,9 @@ - (void)reactAddControllerToClosestParent:(UIViewController *)controller #if !TARGET_OS_TV _controller.interactivePopGestureRecognizer.delegate = self; #endif +#ifndef RN_FABRIC_ENABLED [controller didMoveToParentViewController:parentView.reactViewController]; +#endif // On iOS pre 12 we observed that `willShowViewController` delegate method does not always // get triggered when the navigation controller is instantiated. As the only thing we do in // that delegate method is ask nav header to update to the current state it does not hurt to @@ -941,7 +945,7 @@ - (void)didUpdateReactSubviews }); } -#endif +#endif // RN_FABRIC_ENABLED @end From 34f8cb3e63aef28cffb432b58f6f7b0b5fbbd94f Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:34 +0200 Subject: [PATCH 037/156] chore: merge setModalViewControllers: methods --- ios/RNSScreenStack.mm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 9897b6d134..8155e9f9d6 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -274,6 +274,7 @@ - (void)maybeAddToParentAndUpdateContainer } } +// done - (void)reactAddControllerToClosestParent:(UIViewController *)controller { if (!controller.parentViewController) { @@ -301,6 +302,7 @@ - (void)reactAddControllerToClosestParent:(UIViewController *)controller } } +// done - (void)setModalViewControllers:(NSArray *)controllers { // prevent re-entry @@ -351,9 +353,12 @@ - (void)setModalViewControllers:(NSArray *)controllers __weak RNSScreenStackView *weakSelf = self; void (^afterTransitions)(void) = ^{ + // TODO: Implement onFinishTransitioning on Fabric +#ifndef RN_FABRIC_ENABLED if (weakSelf.onFinishTransitioning) { weakSelf.onFinishTransitioning(nil); } +#endif weakSelf.updatingModals = NO; if (weakSelf.scheduleModalsUpdate) { // if modals update was requested during setModalViewControllers we set scheduleModalsUpdate From ee139da061669c9f61dc0e740f81f352913839a8 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:36 +0200 Subject: [PATCH 038/156] chore: WIP: merge setPushViewControllers --- ios/RNSScreenStack.mm | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 8155e9f9d6..ad5302253f 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -437,6 +437,7 @@ - (void)setModalViewControllers:(NSArray *)controllers } } +// done - (void)setPushViewControllers:(NSArray *)controllers { // when there is no change we return immediately @@ -472,6 +473,56 @@ - (void)setPushViewControllers:(NSArray *)controllers } UIViewController *top = controllers.lastObject; +#ifdef RN_FABRIC_ENABLED + UIViewController *previousTop = _controller.topViewController; + + // At the start we set viewControllers to contain a single UIViewController + // instance. This is a workaround for header height adjustment bug (see comment + // in the init function). Here, we need to detect if the initial empty + // controller is still there + BOOL firstTimePush = ![previousTop isKindOfClass:[RNSScreen class]]; + + if (firstTimePush) { + // nothing pushed yet + [_controller setViewControllers:controllers animated:NO]; + } else if (top != previousTop) { + if (![controllers containsObject:previousTop]) { + // if the previous top screen does not exist anymore and the new top was not on the stack before, probably replace + // was called, so we check the animation + if (![_controller.viewControllers containsObject:top]) { + // setting new controllers with animation does `push` animation by default + auto screenController = (RNSScreen *)top; + [screenController resetViewToScreen]; + [_controller setViewControllers:controllers animated:YES]; + } else { + // last top controller is no longer on stack + // in this case we set the controllers stack to the new list with + // added the last top element to it and perform (animated) pop + NSMutableArray *newControllers = [NSMutableArray arrayWithArray:controllers]; + [newControllers addObject:previousTop]; + [_controller setViewControllers:newControllers animated:NO]; + [_controller popViewControllerAnimated:YES]; + } + } else if (![_controller.viewControllers containsObject:top]) { + // new top controller is not on the stack + // in such case we update the stack except from the last element with + // no animation and do animated push of the last item + NSMutableArray *newControllers = [NSMutableArray arrayWithArray:controllers]; + [newControllers removeLastObject]; + [_controller setViewControllers:newControllers animated:NO]; + auto screenController = (RNSScreen *)top; + [screenController resetViewToScreen]; + [_controller pushViewController:top animated:YES]; + } else { + // don't really know what this case could be, but may need to handle it + // somehow + [_controller setViewControllers:controllers animated:YES]; + } + } else { + // change wasn't on the top of the stack. We don't need animation. + [_controller setViewControllers:controllers animated:NO]; + } +#else UIViewController *lastTop = _controller.viewControllers.lastObject; // at the start we set viewControllers to contain a single UIVIewController @@ -519,6 +570,7 @@ - (void)setPushViewControllers:(NSArray *)controllers // change wasn't on the top of the stack. We don't need animation. [_controller setViewControllers:controllers animated:NO]; } +#endif } - (void)updateContainer From ed24d05f96e09510b9505bfb0f2303948b54eef2 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:38 +0200 Subject: [PATCH 039/156] chore: merge updateContainer methods --- ios/RNSScreenStack.mm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index ad5302253f..b31f10fb88 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -573,13 +573,17 @@ - (void)setPushViewControllers:(NSArray *)controllers #endif } +// done - (void)updateContainer { -#ifndef RN_FABRIC_ENABLED NSMutableArray *pushControllers = [NSMutableArray new]; NSMutableArray *modalControllers = [NSMutableArray new]; for (RNSScreenView *screen in _reactSubviews) { +#ifdef RN_FABRIC_ENABLED + if (screen.controller != nil) { +#else if (!screen.dismissed && screen.controller != nil) { +#endif if (pushControllers.count == 0) { // first screen on the list needs to be places as "push controller" [pushControllers addObject:screen.controller]; @@ -595,7 +599,6 @@ - (void)updateContainer [self setPushViewControllers:pushControllers]; [self setModalViewControllers:modalControllers]; -#endif } // By default, the header buttons that are not inside the native hit area From 8140571dc9840392c3b8e555288c59a87ff07fda Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:40 +0200 Subject: [PATCH 040/156] chore: move hitTest:withEvent: method to paper specific section --- ios/RNSScreenStack.mm | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index b31f10fb88..86645b4e65 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -601,23 +601,6 @@ - (void)updateContainer [self setModalViewControllers:modalControllers]; } -// By default, the header buttons that are not inside the native hit area -// cannot be clicked, so we check it by ourselves -- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event -{ - if (CGRectContainsPoint(_controller.navigationBar.frame, point)) { - // headerConfig should be the first subview of the topmost screen - UIView *headerConfig = [[_reactSubviews.lastObject reactSubviews] firstObject]; - if ([headerConfig isKindOfClass:[RNSScreenStackHeaderConfig class]]) { - UIView *headerHitTestResult = [headerConfig hitTest:point withEvent:event]; - if (headerHitTestResult != nil) { - return headerHitTestResult; - } - } - } - return [super hitTest:point withEvent:event]; -} - - (void)layoutSubviews { [super layoutSubviews]; @@ -1005,6 +988,22 @@ - (void)didUpdateReactSubviews }); } +// By default, the header buttons that are not inside the native hit area +// cannot be clicked, so we check it by ourselves +- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event +{ + if (CGRectContainsPoint(_controller.navigationBar.frame, point)) { + // headerConfig should be the first subview of the topmost screen + UIView *headerConfig = [[_reactSubviews.lastObject reactSubviews] firstObject]; + if ([headerConfig isKindOfClass:[RNSScreenStackHeaderConfig class]]) { + UIView *headerHitTestResult = [headerConfig hitTest:point withEvent:event]; + if (headerHitTestResult != nil) { + return headerHitTestResult; + } + } + } + return [super hitTest:point withEvent:event]; +} #endif // RN_FABRIC_ENABLED @end From 899b2850baf2152964dd8da2a8ca9ce25d1e13de Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:42 +0200 Subject: [PATCH 041/156] refact: fix braces in updateContainer method --- ios/RNSScreenStack.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 86645b4e65..c1be185fd0 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -580,10 +580,11 @@ - (void)updateContainer NSMutableArray *modalControllers = [NSMutableArray new]; for (RNSScreenView *screen in _reactSubviews) { #ifdef RN_FABRIC_ENABLED - if (screen.controller != nil) { + if (screen.controller != nil) #else - if (!screen.dismissed && screen.controller != nil) { + if (!screen.dismissed && screen.controller != nil) #endif + { if (pushControllers.count == 0) { // first screen on the list needs to be places as "push controller" [pushControllers addObject:screen.controller]; @@ -601,6 +602,7 @@ - (void)updateContainer [self setModalViewControllers:modalControllers]; } +// done - (void)layoutSubviews { [super layoutSubviews]; From 35fd105ede1954b0452326b02f45d80fd54c79cf Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:44 +0200 Subject: [PATCH 042/156] chore: move invalidate method to paper specific section --- ios/RNSScreenStack.mm | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index c1be185fd0..4adc9df960 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -609,17 +609,6 @@ - (void)layoutSubviews _controller.view.frame = self.bounds; } -- (void)invalidate -{ - _invalidated = YES; - for (UIViewController *controller in _presentedModals) { - [controller dismissViewControllerAnimated:NO completion:nil]; - } - [_presentedModals removeAllObjects]; - [_controller willMoveToParentViewController:nil]; - [_controller removeFromParentViewController]; -} - - (void)dismissOnReload { dispatch_async(dispatch_get_main_queue(), ^{ @@ -1006,6 +995,18 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event } return [super hitTest:point withEvent:event]; } + +- (void)invalidate +{ + _invalidated = YES; + for (UIViewController *controller in _presentedModals) { + [controller dismissViewControllerAnimated:NO completion:nil]; + } + [_presentedModals removeAllObjects]; + [_controller willMoveToParentViewController:nil]; + [_controller removeFromParentViewController]; +} + #endif // RN_FABRIC_ENABLED @end From bc27beb626cc9c02b3f198832ed0550e4a64bebb Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:46 +0200 Subject: [PATCH 043/156] chore: merge dismissOnReload methods --- ios/RNSScreenStack.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 4adc9df960..60322fd1e7 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -609,11 +609,17 @@ - (void)layoutSubviews _controller.view.frame = self.bounds; } +// done - (void)dismissOnReload { +#ifdef RN_FABRIC_ENABLED + auto screenController = (RNSScreen *)_controller.topViewController; + [screenController resetViewToScreen]; +#else dispatch_async(dispatch_get_main_queue(), ^{ [self invalidate]; }); +#endif } #pragma mark methods connected to transitioning From 0c57d95f16396ee443a9da41dfe76da06414ad33 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:48 +0200 Subject: [PATCH 044/156] chore: move isInGestureResponseDistance:topScreen: method to paper specific section --- ios/RNSScreenStack.mm | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 60322fd1e7..0565a23ee6 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -624,6 +624,7 @@ - (void)dismissOnReload #pragma mark methods connected to transitioning +// done - (id)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC @@ -644,27 +645,6 @@ - (void)dismissOnReload return nil; } -- (BOOL)isInGestureResponseDistance:(UIGestureRecognizer *)gestureRecognizer topScreen:(RNSScreenView *)topScreen -{ -#ifndef RN_FABRIC_ENABLED - NSDictionary *gestureResponseDistanceValues = topScreen.gestureResponseDistance; - float x = [gestureRecognizer locationInView:gestureRecognizer.view].x; - float y = [gestureRecognizer locationInView:gestureRecognizer.view].y; - BOOL isRTL = _controller.view.semanticContentAttribute == UISemanticContentAttributeForceRightToLeft; - if (isRTL) { - x = _controller.view.frame.size.width - x; - } - // we check if any of the constraints are violated and return NO if so - return !( - (gestureResponseDistanceValues[@"start"] && x < [gestureResponseDistanceValues[@"start"] floatValue]) || - (gestureResponseDistanceValues[@"end"] && x > [gestureResponseDistanceValues[@"end"] floatValue]) || - (gestureResponseDistanceValues[@"top"] && y < [gestureResponseDistanceValues[@"top"] floatValue]) || - (gestureResponseDistanceValues[@"bottom"] && y > [gestureResponseDistanceValues[@"bottom"] floatValue])); -#else - return NO; -#endif -} - - (void)cancelTouchesInParent { // cancel touches in parent, this is needed to cancel RN touch events. For example when Touchable @@ -1013,6 +993,23 @@ - (void)invalidate [_controller removeFromParentViewController]; } +- (BOOL)isInGestureResponseDistance:(UIGestureRecognizer *)gestureRecognizer topScreen:(RNSScreenView *)topScreen +{ + NSDictionary *gestureResponseDistanceValues = topScreen.gestureResponseDistance; + float x = [gestureRecognizer locationInView:gestureRecognizer.view].x; + float y = [gestureRecognizer locationInView:gestureRecognizer.view].y; + BOOL isRTL = _controller.view.semanticContentAttribute == UISemanticContentAttributeForceRightToLeft; + if (isRTL) { + x = _controller.view.frame.size.width - x; + } + // we check if any of the constraints are violated and return NO if so + return !( + (gestureResponseDistanceValues[@"start"] && x < [gestureResponseDistanceValues[@"start"] floatValue]) || + (gestureResponseDistanceValues[@"end"] && x > [gestureResponseDistanceValues[@"end"] floatValue]) || + (gestureResponseDistanceValues[@"top"] && y < [gestureResponseDistanceValues[@"top"] floatValue]) || + (gestureResponseDistanceValues[@"bottom"] && y > [gestureResponseDistanceValues[@"bottom"] floatValue])); + return NO; +} #endif // RN_FABRIC_ENABLED @end From 844820ca3a9078541e68379423783c9d757fee65 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:50 +0200 Subject: [PATCH 045/156] chore: merge cancelTouchesInParent methods --- ios/RNSScreenStack.mm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 0565a23ee6..3c3b6d0455 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -655,9 +655,16 @@ - (void)cancelTouchesInParent while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)]) parent = parent.superview; if (parent != nil) { +#ifdef RN_FABRIC_ENABLED + RCTSurfaceTouchHandler *touchHandler = [parent performSelector:@selector(touchHandler)]; + [touchHandler setEnabled:NO]; + [touchHandler setEnabled:YES]; + [touchHandler reset]; +#else RCTTouchHandler *touchHandler = [parent performSelector:@selector(touchHandler)]; [touchHandler cancel]; [touchHandler reset]; +#endif } } From fa21ff4e81d3d07e18bb47c80e2db0e74956da70 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:52 +0200 Subject: [PATCH 046/156] chore: merge gestureRecognizerShouldBegin: methods --- ios/RNSScreenStack.mm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 3c3b6d0455..83702d1aff 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -645,6 +645,7 @@ - (void)dismissOnReload return nil; } +// done - (void)cancelTouchesInParent { // cancel touches in parent, this is needed to cancel RN touch events. For example when Touchable @@ -668,6 +669,7 @@ - (void)cancelTouchesInParent } } +// done - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view; @@ -684,8 +686,13 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer if (topScreen.fullScreenSwipeEnabled) { // we want only `RNSPanGestureRecognizer` to be able to recognize when // `fullScreenSwipeEnabled` is set, and we are in the bounds set by user +#ifdef RN_FABRIC_ENABLED + if ([gestureRecognizer isKindOfClass:[RNSPanGestureRecognizer class]]) +#else if ([gestureRecognizer isKindOfClass:[RNSPanGestureRecognizer class]] && - [self isInGestureResponseDistance:gestureRecognizer topScreen:topScreen]) { + [self isInGestureResponseDistance:gestureRecognizer topScreen:topScreen]) +#endif + { _isFullWidthSwiping = YES; [self cancelTouchesInParent]; return YES; From 159e07a5bc55197735da7fc912d8b9fe07209985 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:54 +0200 Subject: [PATCH 047/156] chore: move isScrollViewPanGestureRecognizer: method to paper specific section temporary -- unitl not implemented on fabric --- ios/RNSScreenStack.mm | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 83702d1aff..a58246f63c 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -741,18 +741,6 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer #endif } -- (BOOL)isScrollViewPanGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer -{ - // NOTE: This hack is required to restore native behavior of edge swipe (interactive pop gesture) - // without this, on a screen with a scroll view, it's only possible to pop view by panning horizontally - // if even slightly diagonal (or if in motion), scroll view will scroll, and edge swipe will be cancelled - if (![[gestureRecognizer view] isKindOfClass:[UIScrollView class]]) { - return NO; - } - UIScrollView *scrollView = gestureRecognizer.view; - return scrollView.panGestureRecognizer == gestureRecognizer; -} - - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { @@ -1024,6 +1012,19 @@ - (BOOL)isInGestureResponseDistance:(UIGestureRecognizer *)gestureRecognizer top (gestureResponseDistanceValues[@"bottom"] && y > [gestureResponseDistanceValues[@"bottom"] floatValue])); return NO; } + +- (BOOL)isScrollViewPanGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer +{ + // NOTE: This hack is required to restore native behavior of edge swipe (interactive pop gesture) + // without this, on a screen with a scroll view, it's only possible to pop view by panning horizontally + // if even slightly diagonal (or if in motion), scroll view will scroll, and edge swipe will be cancelled + if (![[gestureRecognizer view] isKindOfClass:[UIScrollView class]]) { + return NO; + } + UIScrollView *scrollView = gestureRecognizer.view; + return scrollView.panGestureRecognizer == gestureRecognizer; +} + #endif // RN_FABRIC_ENABLED @end From c5a30934085e1514cfdf5c640ba22d37dbcd4d32 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:56 +0200 Subject: [PATCH 048/156] chore: move two gestureRecognizer:... methods to paper specific section --- ios/RNSScreenStack.mm | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index a58246f63c..4df5a122b8 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -741,17 +741,6 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer #endif } -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer - shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer -{ - return [self isScrollViewPanGestureRecognizer:otherGestureRecognizer]; -} - -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer - shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer -{ - return [self isScrollViewPanGestureRecognizer:otherGestureRecognizer]; -} #if !TARGET_OS_TV - (void)setupGestureHandlers @@ -1025,6 +1014,17 @@ - (BOOL)isScrollViewPanGestureRecognizer:(UIGestureRecognizer *)gestureRecognize return scrollView.panGestureRecognizer == gestureRecognizer; } +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer + shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +{ + return [self isScrollViewPanGestureRecognizer:otherGestureRecognizer]; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer + shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +{ + return [self isScrollViewPanGestureRecognizer:otherGestureRecognizer]; +} #endif // RN_FABRIC_ENABLED @end From f0d45dc61f452eaac0cecbe29fc68366e8ab31f7 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:57 +0200 Subject: [PATCH 049/156] chore: move two interactionController getters to paper specific section --- ios/RNSScreenStack.mm | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 4df5a122b8..0fb88cae5c 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -743,6 +743,7 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer #if !TARGET_OS_TV +// done - (void)setupGestureHandlers { // gesture recognizers for custom stack animations @@ -765,6 +766,7 @@ - (void)setupGestureHandlers [self addGestureRecognizer:panRecognizer]; } +// done - (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer { RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view; @@ -823,19 +825,6 @@ - (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer } #endif -- (id)navigationController:(UINavigationController *)navigationController - interactionControllerForAnimationController: - (id)animationController -{ - return _interactionController; -} - -- (id)interactionControllerForDismissal: - (id)animator -{ - return _interactionController; -} - #ifdef RN_FABRIC_ENABLED #pragma mark - Fabric specific @@ -1025,6 +1014,19 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer { return [self isScrollViewPanGestureRecognizer:otherGestureRecognizer]; } + +- (id)navigationController:(UINavigationController *)navigationController + interactionControllerForAnimationController: + (id)animationController +{ + return _interactionController; +} + +- (id)interactionControllerForDismissal: + (id)animator +{ + return _interactionController; +} #endif // RN_FABRIC_ENABLED @end From 396d58e1835e6c8191813303cea48519debb5fed Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:24:59 +0200 Subject: [PATCH 050/156] chore: move prepareForRecycle method to fabric specific section & finish merging --- ios/RNSScreenStack.mm | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 0fb88cae5c..1261646276 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -890,6 +890,26 @@ - (void)mountingTransactionWillMountWithMetadata:(MountingTransactionMetadata co [self takeSnapshot]; } +- (void)prepareForRecycle +{ + [super prepareForRecycle]; + _reactSubviews = [NSMutableArray new]; + + for (UIViewController *controller in _presentedModals) { + [controller dismissViewControllerAnimated:NO completion:nil]; + } + + [_presentedModals removeAllObjects]; + [self dismissOnReload]; + [_controller willMoveToParentViewController:nil]; + [_controller removeFromParentViewController]; + [_controller setViewControllers:@[ [UIViewController new] ]]; +} + ++ (ComponentDescriptorProvider)componentDescriptorProvider +{ + return concreteComponentDescriptorProvider(); +} #else #pragma mark - Paper specific @@ -1031,6 +1051,12 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer @end +Class RNSScreenStackCls(void) +{ + return RNSScreenStackView.class; +} + +#ifndef RN_FABRIC_ENABLED @implementation RNSScreenStackManager { NSPointerArray *_stacks; } @@ -1058,3 +1084,4 @@ - (void)invalidate } @end +#endif From 7b6653581607c91dda3d22cd11d0ae4d73c3f0b0 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:25:01 +0200 Subject: [PATCH 051/156] fix: add facebook::react namespace to C++ react types --- ios/RNSScreenStack.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 1261646276..b657da1124 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -117,7 +117,7 @@ @implementation RNSScreenStackView { - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { - static const auto defaultProps = std::make_shared(); + static const auto defaultProps = std::make_shared(); _props = defaultProps; _reactSubviews = [NSMutableArray new]; _presentedModals = [NSMutableArray new]; @@ -885,7 +885,7 @@ - (void)takeSnapshot _snapshot = [_controller.topViewController.view snapshotViewAfterScreenUpdates:NO]; } -- (void)mountingTransactionWillMountWithMetadata:(MountingTransactionMetadata const &)metadata +- (void)mountingTransactionWillMountWithMetadata:(facebook::react::MountingTransactionMetadata const &)metadata { [self takeSnapshot]; } @@ -906,9 +906,9 @@ - (void)prepareForRecycle [_controller setViewControllers:@[ [UIViewController new] ]]; } -+ (ComponentDescriptorProvider)componentDescriptorProvider ++ (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider { - return concreteComponentDescriptorProvider(); + return facebook::react::concreteComponentDescriptorProvider(); } #else #pragma mark - Paper specific From 8b212d35731b546463aa948f7c980b781aa8b711 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:25:03 +0200 Subject: [PATCH 052/156] chore: remove RNSScreenStackComponentView.{h,mm} files --- ios/RNSScreenStackComponentView.h | 15 - ios/RNSScreenStackComponentView.mm | 693 ----------------------------- 2 files changed, 708 deletions(-) delete mode 100644 ios/RNSScreenStackComponentView.h delete mode 100644 ios/RNSScreenStackComponentView.mm diff --git a/ios/RNSScreenStackComponentView.h b/ios/RNSScreenStackComponentView.h deleted file mode 100644 index 03915852ce..0000000000 --- a/ios/RNSScreenStackComponentView.h +++ /dev/null @@ -1,15 +0,0 @@ -#import - -#import -#import "RNSScreenContainer.h" - -NS_ASSUME_NONNULL_BEGIN -@interface RNScreensNavigationController : UINavigationController - -@end - -@interface RNSScreenStackComponentView : RCTViewComponentView - -@end - -NS_ASSUME_NONNULL_END diff --git a/ios/RNSScreenStackComponentView.mm b/ios/RNSScreenStackComponentView.mm deleted file mode 100644 index f6635bacf3..0000000000 --- a/ios/RNSScreenStackComponentView.mm +++ /dev/null @@ -1,693 +0,0 @@ -#import "RNSScreenStackComponentView.h" -#import "RNSScreen.h" -#import "RNSScreenStackAnimator.h" -#import "RNSScreenStackHeaderConfigComponentView.h" -#import "RNSScreenWindowTraits.h" - -#import - -#import -#import -#import -#import -#import - -#import "RCTFabricComponentsPlugins.h" - -#import - -using namespace facebook::react; - -@interface RNSScreenStackComponentView () < - UINavigationControllerDelegate, - UIAdaptivePresentationControllerDelegate, - UIGestureRecognizerDelegate, - UIViewControllerTransitioningDelegate, - RCTMountingTransactionObserving> { - BOOL _updateScheduled; -} - -@property (nonatomic) NSMutableArray *presentedModals; -@property (nonatomic) BOOL updatingModals; -@property (nonatomic) BOOL scheduleModalsUpdate; - -@end - -#if !TARGET_OS_TV -@interface RNSScreenEdgeGestureRecognizerF : UIScreenEdgePanGestureRecognizer -@end - -@implementation RNSScreenEdgeGestureRecognizerF -@end - -@interface RNSPanGestureRecognizerF : UIPanGestureRecognizer -@end - -@implementation RNSPanGestureRecognizerF -@end -#endif - -@implementation RNSScreenStackComponentView { - UINavigationController *_controller; - NSMutableArray *_reactSubviews; - BOOL _invalidated; - UIView *_snapshot; - BOOL _isFullWidthSwiping; - UIPercentDrivenInteractiveTransition *_interactionController; -} - -- (instancetype)initWithFrame:(CGRect)frame -{ - if (self = [super initWithFrame:frame]) { - static const auto defaultProps = std::make_shared(); - _props = defaultProps; - _reactSubviews = [NSMutableArray new]; - _presentedModals = [NSMutableArray new]; - _controller = [RNScreensNavigationController new]; - _controller.delegate = self; - [_controller setViewControllers:@[ [UIViewController new] ]]; -#if !TARGET_OS_TV - [self setupGestureHandlers]; -#endif - } - - return self; -} - -- (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index -{ - // TODO: Remove this if def when merging with RNSScreenStack -#ifdef RN_FABRIC_ENABLED - if (![childComponentView isKindOfClass:[RNSScreenView class]]) { - RCTLogError(@"ScreenStack only accepts children of type Screen"); - return; - } - - RCTAssert( - childComponentView.reactSuperview == nil, - @"Attempt to mount already mounted component view. (parent: %@, child: %@, index: %@, existing parent: %@)", - self, - childComponentView, - @(index), - @([childComponentView.superview tag])); - - [_reactSubviews insertObject:(RNSScreenView *)childComponentView atIndex:index]; - ((RNSScreenView *)childComponentView).reactSuperview = self; - dispatch_async(dispatch_get_main_queue(), ^{ - [self maybeAddToParentAndUpdateContainer]; - }); -#endif -} - -- (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index -{ - // TODO: Remove this if def when merging with RNSScreenStack -#ifdef RN_FABRIC_ENABLED - RNSScreenView *screenChildComponent = (RNSScreenView *)childComponentView; - // We should only do a snapshot of a screen that is on the top - if (screenChildComponent == _controller.topViewController.view) { - [screenChildComponent.controller setViewToSnapshot:_snapshot]; - } - - RCTAssert( - screenChildComponent.reactSuperview == self, - @"Attempt to unmount a view which is mounted inside different view. (parent: %@, child: %@, index: %@)", - self, - screenChildComponent, - @(index)); - RCTAssert( - (_reactSubviews.count > index) && [_reactSubviews objectAtIndex:index] == childComponentView, - @"Attempt to unmount a view which has a different index. (parent: %@, child: %@, index: %@, actual index: %@, tag at index: %@)", - self, - screenChildComponent, - @(index), - @([_reactSubviews indexOfObject:screenChildComponent]), - @([[_reactSubviews objectAtIndex:index] tag])); - screenChildComponent.reactSuperview = nil; - [_reactSubviews removeObject:screenChildComponent]; - [screenChildComponent removeFromSuperview]; - dispatch_async(dispatch_get_main_queue(), ^{ - [self maybeAddToParentAndUpdateContainer]; - }); -#endif -} - -- (void)takeSnapshot -{ - _snapshot = [_controller.topViewController.view snapshotViewAfterScreenUpdates:NO]; -} - -- (void)mountingTransactionWillMountWithMetadata:(MountingTransactionMetadata const &)metadata -{ - [self takeSnapshot]; -} - -- (NSArray *)reactSubviews -{ - return _reactSubviews; -} - -- (void)didMoveToWindow -{ - [super didMoveToWindow]; - // for handling nested stacks - [self maybeAddToParentAndUpdateContainer]; -} - -- (void)navigationController:(UINavigationController *)navigationController - willShowViewController:(UIViewController *)viewController - animated:(BOOL)animated -{ - // TODO: Remove this if def when merging with RNSScreenStack -#ifdef RN_FABRIC_ENABLED - - UIView *view = viewController.view; - if ([view isKindOfClass:RNSScreenView.class]) { - RNSScreenStackHeaderConfigComponentView *config = - (RNSScreenStackHeaderConfigComponentView *)((RNSScreenView *)view).config; - [RNSScreenStackHeaderConfigComponentView willShowViewController:viewController animated:animated withConfig:config]; - } -#endif -} - -- (void)maybeAddToParentAndUpdateContainer -{ - BOOL wasScreenMounted = _controller.parentViewController != nil; - BOOL isScreenReadyForShowing = self.window; - if (!isScreenReadyForShowing && !wasScreenMounted) { - return; - } - [self updateContainer]; - if (!wasScreenMounted) { - // when stack hasn't been added to parent VC yet we do two things: - // 1) we run updateContainer (the one above) – we do this because we want push view controllers to - // be installed before the VC is mounted. If we do that after it is added to parent the push - // updates operations are going to be blocked by UIKit. - // 2) we add navigation VS to parent – this is needed for the VC lifecycle events to be dispatched - // properly - // 3) we again call updateContainer – this time we do this to open modal controllers. Modals - // won't open in (1) because they require navigator to be added to parent. We handle that case - // gracefully in setModalViewControllers and can retry opening at any point. - [self reactAddControllerToClosestParent:_controller]; - [self updateContainer]; - } -} - -- (void)reactAddControllerToClosestParent:(UIViewController *)controller -{ - if (!controller.parentViewController) { - UIView *parentView = (UIView *)self.reactSuperview; - while (parentView) { - if ([parentView reactViewController]) { - [parentView.reactViewController addChildViewController:controller]; - [self addSubview:controller.view]; -#if !TARGET_OS_TV - _controller.interactivePopGestureRecognizer.delegate = self; -#endif - [self navigationController:_controller willShowViewController:_controller.topViewController animated:NO]; - break; - } - parentView = (UIView *)parentView.reactSuperview; - } - return; - } -} - -- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController -{ - // We don't directly set presentation delegate but instead rely on the ScreenView's delegate to - // forward certain calls to the container (Stack). - UIView *screenView = presentationController.presentedViewController.view; - if ([screenView isKindOfClass:[RNSScreenView class]]) { - // we trigger the update of status bar's appearance here because there is no other lifecycle method - // that can handle it when dismissing a modal, the same for orientation - [RNSScreenWindowTraits updateWindowTraits]; - [_presentedModals removeObject:presentationController.presentedViewController]; - // we double check if there are no new controllers pending to be presented since someone could - // have tried to push another one during the transition - _updatingModals = NO; - [self updateContainer]; - // TODO: implement onFinishTransitioning - // if (self.onFinishTransitioning) { - // // instead of directly triggering onFinishTransitioning this time we enqueue the event on the - // // main queue. We do that because onDismiss event is also enqueued and we want for the transition - // // finish event to arrive later than onDismiss (see RNSScreen#notifyDismiss) - // dispatch_async(dispatch_get_main_queue(), ^{ - // if (self.onFinishTransitioning) { - // self.onFinishTransitioning(nil); - // } - // }); - // } - } -} - -- (void)setPushViewControllers:(NSArray *)controllers -{ - // TODO: Remove this if def when merging with RNSScreenStack -#ifdef RN_FABRIC_ENABLED - - // when there is no change we return immediately - if ([_controller.viewControllers isEqualToArray:controllers]) { - return; - } - - // if view controller is not yet attached to window we skip updates now and run them when view - // is attached - if (self.window == nil) { - return; - } - - // when transition is ongoing, any updates made to the controller will not be reflected until the - // transition is complete. In particular, when we push/pop view controllers we expect viewControllers - // property to be updated immediately. Based on that property we then calculate future updates. - // When the transition is ongoing the property won't be updated immediatly. We therefore avoid - // making any updated when transition is ongoing and schedule updates for when the transition - // is complete. - if (_controller.transitionCoordinator != nil) { - if (!_updateScheduled) { - _updateScheduled = YES; - __weak RNSScreenStackComponentView *weakSelf = self; - [_controller.transitionCoordinator - animateAlongsideTransition:^(id _Nonnull context) { - // do nothing here, we only want to be notified when transition is complete - } - completion:^(id _Nonnull context) { - self->_updateScheduled = NO; - [weakSelf updateContainer]; - }]; - } - return; - } - - UIViewController *top = controllers.lastObject; - UIViewController *previousTop = _controller.topViewController; - - // At the start we set viewControllers to contain a single UIViewController - // instance. This is a workaround for header height adjustment bug (see comment - // in the init function). Here, we need to detect if the initial empty - // controller is still there - BOOL firstTimePush = ![previousTop isKindOfClass:[RNSScreen class]]; - - if (firstTimePush) { - // nothing pushed yet - [_controller setViewControllers:controllers animated:NO]; - } else if (top != previousTop) { - if (![controllers containsObject:previousTop]) { - // if the previous top screen does not exist anymore and the new top was not on the stack before, probably replace - // was called, so we check the animation - if (![_controller.viewControllers containsObject:top]) { - // setting new controllers with animation does `push` animation by default - auto screenController = (RNSScreen *)top; - [screenController resetViewToScreen]; - [_controller setViewControllers:controllers animated:YES]; - } else { - // last top controller is no longer on stack - // in this case we set the controllers stack to the new list with - // added the last top element to it and perform (animated) pop - NSMutableArray *newControllers = [NSMutableArray arrayWithArray:controllers]; - [newControllers addObject:previousTop]; - [_controller setViewControllers:newControllers animated:NO]; - [_controller popViewControllerAnimated:YES]; - } - } else if (![_controller.viewControllers containsObject:top]) { - // new top controller is not on the stack - // in such case we update the stack except from the last element with - // no animation and do animated push of the last item - NSMutableArray *newControllers = [NSMutableArray arrayWithArray:controllers]; - [newControllers removeLastObject]; - [_controller setViewControllers:newControllers animated:NO]; - auto screenController = (RNSScreen *)top; - [screenController resetViewToScreen]; - [_controller pushViewController:top animated:YES]; - } else { - // don't really know what this case could be, but may need to handle it - // somehow - [_controller setViewControllers:controllers animated:YES]; - } - } else { - // change wasn't on the top of the stack. We don't need animation. - [_controller setViewControllers:controllers animated:NO]; - } -#endif -} - -- (void)setModalViewControllers:(NSArray *)controllers -{ - // prevent re-entry - if (_updatingModals) { - _scheduleModalsUpdate = YES; - return; - } - - // when there is no change we return immediately. This check is important because sometime we may - // accidently trigger modal dismiss if we don't verify to run the below code only when an actual - // change in the list of presented modal was made. - if ([_presentedModals isEqualToArray:controllers]) { - return; - } - - // if view controller is not yet attached to window we skip updates now and run them when view - // is attached - if (self.window == nil && _presentedModals.lastObject.view.window == nil) { - return; - } - - _updatingModals = YES; - - NSMutableArray *newControllers = [NSMutableArray arrayWithArray:controllers]; - [newControllers removeObjectsInArray:_presentedModals]; - - // find bottom-most controller that should stay on the stack for the duration of transition - NSUInteger changeRootIndex = 0; - UIViewController *changeRootController = _controller; - for (NSUInteger i = 0; i < MIN(_presentedModals.count, controllers.count); i++) { - if (_presentedModals[i] == controllers[i]) { - changeRootController = controllers[i]; - changeRootIndex = i + 1; - } else { - break; - } - } - - // we verify that controllers added on top of changeRootIndex are all new. Unfortunately modal - // VCs cannot be reshuffled (there are some visual glitches when we try to dismiss then show as - // even non-animated dismissal has delay and updates the screen several times) - for (NSUInteger i = changeRootIndex; i < controllers.count; i++) { - if ([_presentedModals containsObject:controllers[i]]) { - RCTAssert(false, @"Modally presented controllers are being reshuffled, this is not allowed"); - } - } - - __weak RNSScreenStackComponentView *weakSelf = self; - - void (^afterTransitions)(void) = ^{ - // TODO: find out how to implement these - // if (weakSelf.onFinishTransitioning) { - // weakSelf.onFinishTransitioning(nil); - // } - weakSelf.updatingModals = NO; - if (weakSelf.scheduleModalsUpdate) { - // if modals update was requested during setModalViewControllers we set scheduleModalsUpdate - // flag in order to perform updates at a later point. Here we are done with all modals - // transitions and check this flag again. If it was set, we reset the flag and execute updates. - weakSelf.scheduleModalsUpdate = NO; - [weakSelf updateContainer]; - } - // we trigger the update of orientation here because, when dismissing the modal from JS, - // neither `viewWillAppear` nor `presentationControllerDidDismiss` are called, same for status bar. - [RNSScreenWindowTraits updateWindowTraits]; - }; - - void (^finish)(void) = ^{ - NSUInteger oldCount = weakSelf.presentedModals.count; - if (changeRootIndex < oldCount) { - [weakSelf.presentedModals removeObjectsInRange:NSMakeRange(changeRootIndex, oldCount - changeRootIndex)]; - } - BOOL isAttached = - changeRootController.parentViewController != nil || changeRootController.presentingViewController != nil; - if (!isAttached || changeRootIndex >= controllers.count) { - // if change controller view is not attached, presenting modals will silently fail on iOS. - // In such a case we trigger controllers update from didMoveToWindow. - // We also don't run any present transitions if changeRootIndex is greater or equal to the size - // of new controllers array. This means that no new controllers should be presented. - afterTransitions(); - return; - } else { - UIViewController *previous = changeRootController; - for (NSUInteger i = changeRootIndex; i < controllers.count; i++) { - UIViewController *next = controllers[i]; - BOOL lastModal = (i == controllers.count - 1); - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \ - __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 - if (@available(iOS 13.0, tvOS 13.0, *)) { - // Inherit UI style from its parent - solves an issue with incorrect style being applied to some UIKit views - // like date picker or segmented control. - next.overrideUserInterfaceStyle = self->_controller.overrideUserInterfaceStyle; - } -#endif - - BOOL shouldAnimate = lastModal && [next isKindOfClass:[RNSScreen class]] && - ((RNSScreenView *)next.view).stackAnimation != RNSScreenStackAnimationNone; - - // if you want to present another modal quick enough after dismissing the previous one, - // it will result in wrong changeRootController, see repro in - // https://github.com/software-mansion/react-native-screens/issues/1299 We call `updateContainer` again in - // `presentationControllerDidDismiss` to cover this case and present new controller - if (previous.beingDismissed) { - return; - } - - [previous presentViewController:next - animated:shouldAnimate - completion:^{ - [weakSelf.presentedModals addObject:next]; - if (lastModal) { - afterTransitions(); - }; - }]; - previous = next; - } - } - }; - - if (changeRootController.presentedViewController != nil && - [_presentedModals containsObject:changeRootController.presentedViewController]) { - BOOL shouldAnimate = changeRootIndex == controllers.count && - [changeRootController.presentedViewController isKindOfClass:[RNSScreen class]] && - ((RNSScreenView *)changeRootController.presentedViewController.view).stackAnimation != - RNSScreenStackAnimationNone; - [changeRootController dismissViewControllerAnimated:shouldAnimate completion:finish]; - } else { - finish(); - } -} - -- (void)updateContainer -{ - NSMutableArray *pushControllers = [NSMutableArray new]; - NSMutableArray *modalControllers = [NSMutableArray new]; - for (RNSScreenView *screen in _reactSubviews) { - if (screen.controller != nil) { - if (pushControllers.count == 0) { - // first screen on the list needs to be places as "push controller" - [pushControllers addObject:screen.controller]; - } else { - if (screen.stackPresentation == RNSScreenStackPresentationPush) { - [pushControllers addObject:screen.controller]; - } else { - [modalControllers addObject:screen.controller]; - } - } - } - } - - [self setPushViewControllers:pushControllers]; - [self setModalViewControllers:modalControllers]; -} - -- (void)layoutSubviews -{ - [super layoutSubviews]; - _controller.view.frame = self.bounds; -} - -- (void)dismissOnReload -{ - // TODO: Remove this ifdef when merging with RNSScreenStack -#ifdef RN_FABRIC_ENABLED - auto screenController = (RNSScreen *)_controller.topViewController; - [screenController resetViewToScreen]; -#endif -} - -#pragma mark - methods connected to transitioning - -- (id)navigationController:(UINavigationController *)navigationController - animationControllerForOperation:(UINavigationControllerOperation)operation - fromViewController:(UIViewController *)fromVC - toViewController:(UIViewController *)toVC -{ - RNSScreenView *screen; - if (operation == UINavigationControllerOperationPush) { - screen = (RNSScreenView *)toVC.view; - } else if (operation == UINavigationControllerOperationPop) { - screen = (RNSScreenView *)fromVC.view; - } - if (screen != nil && - // we need to return the animator when full width swiping even if the animation is not custom, - // otherwise the screen will be just popped immediately due to no animation - (_isFullWidthSwiping || [RNSScreenStackAnimator isCustomAnimation:screen.stackAnimation])) { - return [[RNSScreenStackAnimator alloc] initWithOperation:operation]; - } - return nil; -} - -- (void)cancelTouchesInParent -{ - // cancel touches in parent, this is needed to cancel RN touch events. For example when Touchable - // item is close to an edge and we start pulling from edge we want the Touchable to be cancelled. - // Without the below code the Touchable will remain active (highlighted) for the duration of back - // gesture and onPress may fire when we release the finger. - UIView *parent = _controller.view; - while (parent != nil && ![parent respondsToSelector:@selector(touchHandler)]) - parent = parent.superview; - - if (parent != nil) { - RCTSurfaceTouchHandler *touchHandler = [parent performSelector:@selector(touchHandler)]; - [touchHandler setEnabled:NO]; - [touchHandler setEnabled:YES]; - [touchHandler reset]; - } -} - -- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer -{ - RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view; - - if (![topScreen isKindOfClass:[RNSScreenView class]] || !topScreen.gestureEnabled || - _controller.viewControllers.count < 2) { - return NO; - } - -#if TARGET_OS_TV - [self cancelTouchesInPartent]; - return YES; -#else - - if (topScreen.fullScreenSwipeEnabled) { - // we want only `RNSPanGestureRecognizer` to be able to recognize when - // `fullScreenSwipeEnabled` is set - if ([gestureRecognizer isKindOfClass:[RNSPanGestureRecognizerF class]]) { - _isFullWidthSwiping = YES; - [self cancelTouchesInParent]; - return YES; - } - return NO; - } - - if ([gestureRecognizer isKindOfClass:[RNSScreenEdgeGestureRecognizerF class]]) { - // it should only recognize with `customAnimationOnSwipe` set - return NO; - } else if ([gestureRecognizer isKindOfClass:[RNSPanGestureRecognizerF class]]) { - // it should only recognize with `fullScreenSwipeEnabled` set - return NO; - } - [self cancelTouchesInParent]; - return _controller.viewControllers.count >= 2; - - // TODO: add code for customAnimationOnSwipe prop here -#endif -} - -#if !TARGET_OS_TV -- (void)setupGestureHandlers -{ - // gesture recognizers for custom stack animations - RNSScreenEdgeGestureRecognizerF *leftEdgeSwipeGestureRecognizer = - [[RNSScreenEdgeGestureRecognizerF alloc] initWithTarget:self action:@selector(handleSwipe:)]; - leftEdgeSwipeGestureRecognizer.edges = UIRectEdgeLeft; - leftEdgeSwipeGestureRecognizer.delegate = self; - [self addGestureRecognizer:leftEdgeSwipeGestureRecognizer]; - - RNSScreenEdgeGestureRecognizerF *rightEdgeSwipeGestureRecognizer = - [[RNSScreenEdgeGestureRecognizerF alloc] initWithTarget:self action:@selector(handleSwipe:)]; - rightEdgeSwipeGestureRecognizer.edges = UIRectEdgeRight; - rightEdgeSwipeGestureRecognizer.delegate = self; - - // gesture recognizer for full width swipe gesture - RNSPanGestureRecognizerF *panRecognizer = [[RNSPanGestureRecognizerF alloc] initWithTarget:self - action:@selector(handleSwipe:)]; - panRecognizer.delegate = self; - [self addGestureRecognizer:panRecognizer]; -} - -- (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer -{ - RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view; - - float translation; - float velocity; - float distance; - - if (topScreen.swipeDirection == RNSScreenSwipeDirectionVertical) { - translation = [gestureRecognizer translationInView:gestureRecognizer.view].y; - velocity = [gestureRecognizer velocityInView:gestureRecognizer.view].y; - distance = gestureRecognizer.view.bounds.size.height; - } else { - translation = [gestureRecognizer translationInView:gestureRecognizer.view].x; - velocity = [gestureRecognizer velocityInView:gestureRecognizer.view].x; - distance = gestureRecognizer.view.bounds.size.width; - BOOL isRTL = _controller.view.semanticContentAttribute == UISemanticContentAttributeForceRightToLeft; - if (isRTL) { - translation = -translation; - velocity = -velocity; - } - } - - float transitionProgress = (translation / distance); - - switch (gestureRecognizer.state) { - case UIGestureRecognizerStateBegan: { - _interactionController = [UIPercentDrivenInteractiveTransition new]; - [_controller popViewControllerAnimated:YES]; - break; - } - - case UIGestureRecognizerStateChanged: { - [_interactionController updateInteractiveTransition:transitionProgress]; - break; - } - - case UIGestureRecognizerStateCancelled: { - [_interactionController cancelInteractiveTransition]; - break; - } - - case UIGestureRecognizerStateEnded: { - // values taken from - // https://github.com/react-navigation/react-navigation/blob/54739828598d7072c1bf7b369659e3682db3edc5/packages/stack/src/views/Stack/Card.tsx#L316 - BOOL shouldFinishTransition = (translation + velocity * 0.3) > (distance / 2); - if (shouldFinishTransition) { - [_interactionController finishInteractiveTransition]; - } else { - [_interactionController cancelInteractiveTransition]; - } - _interactionController = nil; - } - default: { - break; - } - } -} -#endif - -#pragma mark - RCTComponentViewProtocol - -- (void)prepareForRecycle -{ - [super prepareForRecycle]; - _reactSubviews = [NSMutableArray new]; - - for (UIViewController *controller in _presentedModals) { - [controller dismissViewControllerAnimated:NO completion:nil]; - } - - [_presentedModals removeAllObjects]; - [self dismissOnReload]; - [_controller willMoveToParentViewController:nil]; - [_controller removeFromParentViewController]; - [_controller setViewControllers:@[ [UIViewController new] ]]; -} - -+ (ComponentDescriptorProvider)componentDescriptorProvider -{ - return concreteComponentDescriptorProvider(); -} - -@end - -Class RNSScreenStackCls(void) -{ - return RNSScreenStackComponentView.class; -} From 7ea700574fcc0b940dfe057c706f1ab6d41ddccc Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:25:05 +0200 Subject: [PATCH 053/156] chore: add TODOs --- ios/RNSScreenStack.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index b657da1124..f4fea2d859 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -1,4 +1,5 @@ #ifdef RN_FABRIC_ENABLED +// TODO: merge this import when StackHeaderConfigComponentView is merged #import "RNSScreenStackHeaderConfigComponentView.h" #import From 7755d0649aae3077122ed4fd803b0dcbea2f38c9 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:34:46 +0200 Subject: [PATCH 054/156] chore: merge headers --- ios/RNSScreenStackHeaderConfig.h | 35 ++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h index d3d98322c4..7ecad53f9e 100644 --- a/ios/RNSScreenStackHeaderConfig.h +++ b/ios/RNSScreenStackHeaderConfig.h @@ -1,13 +1,35 @@ -#import +#ifdef RN_FABRIC_ENABLED +#import +#import +#import "RNSScreenStackHeaderSubviewComponentView.h" +#else #import +// TODO: move this import when SearchBar is implemented on Fabric +#import "RNSSearchBar.h" +#endif +#import #import "RNSScreen.h" -#import "RNSSearchBar.h" -@interface RNSScreenStackHeaderConfig : UIView +@interface RNSScreenStackHeaderConfig : +#ifdef RN_FABRIC_ENABLED + RCTViewComponentView +#else + UIView +#endif @property (nonatomic, weak) RNSScreenView *screenView; +#ifdef RN_FABRIC_ENABLED +// TODO: change type when StackHeaderSubview is merged (??) +@property (nonatomic) NSMutableArray *reactSubviews; +@property (nonatomic) BOOL show; +#else +@property (nonatomic) UIBlurEffectStyle blurEffect; +@property (nonatomic) BOOL hide; +@property (nonatomic) BOOL backButtonInCustomView; +#endif + @property (nonatomic, retain) NSString *title; @property (nonatomic, retain) NSString *titleFontFamily; @property (nonatomic, retain) NSNumber *titleFontSize; @@ -17,9 +39,7 @@ @property (nonatomic, retain) NSString *backTitleFontFamily; @property (nonatomic, retain) NSNumber *backTitleFontSize; @property (nonatomic, retain) UIColor *backgroundColor; -@property (nonatomic) UIBlurEffectStyle blurEffect; @property (nonatomic, retain) UIColor *color; -@property (nonatomic) BOOL hide; @property (nonatomic) BOOL largeTitle; @property (nonatomic, retain) NSString *largeTitleFontFamily; @property (nonatomic, retain) NSNumber *largeTitleFontSize; @@ -28,7 +48,6 @@ @property (nonatomic) BOOL largeTitleHideShadow; @property (nonatomic, retain) UIColor *largeTitleColor; @property (nonatomic) BOOL hideBackButton; -@property (nonatomic) BOOL backButtonInCustomView; @property (nonatomic) BOOL disableBackButtonMenu; @property (nonatomic) BOOL hideShadow; @property (nonatomic) BOOL translucent; @@ -40,9 +59,11 @@ @end +#ifndef RN_FABRIC_ENABLED @interface RNSScreenStackHeaderConfigManager : RCTViewManager @end +#endif typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) { RNSScreenStackHeaderSubviewTypeBackButton, @@ -61,8 +82,10 @@ typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) { @end +#ifndef RN_FABRIC_ENABLED @interface RNSScreenStackHeaderSubviewManager : RCTViewManager @property (nonatomic) RNSScreenStackHeaderSubviewType type; @end +#endif From 14e2dfa51d3b462e44ef12363aaddbceabf033ab Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:35:22 +0200 Subject: [PATCH 055/156] refact: apply linter suggestions --- ios/RNSScreenStack.mm | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index f4fea2d859..e86e414bf0 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -24,30 +24,27 @@ #import #endif // RN_FABRIC_ENABLED -#import "RNSScreenStack.h" #import "RNSScreen.h" +#import "RNSScreenStack.h" #import "RNSScreenStackAnimator.h" #import "RNSScreenWindowTraits.h" @interface RNSScreenStackView () #ifdef RN_FABRIC_ENABLED -< - UINavigationControllerDelegate, - UIAdaptivePresentationControllerDelegate, - UIGestureRecognizerDelegate, - UIViewControllerTransitioningDelegate, - RCTMountingTransactionObserving> { + { BOOL _updateScheduled; } #else -< - UINavigationControllerDelegate, - UIAdaptivePresentationControllerDelegate, - UIGestureRecognizerDelegate, - UIViewControllerTransitioningDelegate> + #endif - @property (nonatomic) NSMutableArray *presentedModals; @property (nonatomic) BOOL updatingModals; @property (nonatomic) BOOL scheduleModalsUpdate; @@ -354,7 +351,7 @@ - (void)setModalViewControllers:(NSArray *)controllers __weak RNSScreenStackView *weakSelf = self; void (^afterTransitions)(void) = ^{ - // TODO: Implement onFinishTransitioning on Fabric + // TODO: Implement onFinishTransitioning on Fabric #ifndef RN_FABRIC_ENABLED if (weakSelf.onFinishTransitioning) { weakSelf.onFinishTransitioning(nil); @@ -738,11 +735,10 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer [self cancelTouchesInParent]; return _controller.viewControllers.count >= 2; #endif - + #endif } - #if !TARGET_OS_TV // done - (void)setupGestureHandlers From 48c5d5aa3218afc89ef98e43ed3278aebc413830 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:58:27 +0200 Subject: [PATCH 056/156] chore: initial impl setup --- ios/RNSScreenStackHeaderConfig.mm | 64 +++++++++++++++++-------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 5196920037..af0cd724a3 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -1,7 +1,16 @@ -#import "RNSScreenStackHeaderConfig.h" -#import "RNSScreen.h" +#ifdef RN_FABRIC_ENABLED +#import "RNSScreenStackHeaderSubviewComponentView.h" +#import "RCTFabricComponentsPlugins.h" +#import +#import +#import +#import +#import +#import +#import +#else +// TODO: move this import when SearchBar is implemented on Fabric #import "RNSSearchBar.h" - #import #import #import @@ -10,7 +19,13 @@ #import #import #import +#endif +#import "RNSScreenStackHeaderConfig.h" +#import "RNSScreen.h" +#import "./utils/RNSUIBarButtonItem.h" + +#ifndef RN_FABRIC_ENABLED // Some RN private method hacking below. Couldn't figure out better way to access image data // of a given RCTImageView. See more comments in the code section processing SubviewTypeBackButton @interface RCTImageView (Private) @@ -20,6 +35,7 @@ - (UIImage *)image; @interface RCTImageLoader (Private) - (id)imageCache; @end +#endif @interface RNSScreenStackHeaderSubview : UIView @@ -50,37 +66,26 @@ - (void)reactSetFrame:(CGRect)frame @end -@interface RNSUIBarButtonItem : UIBarButtonItem - -@property (nonatomic) BOOL menuHidden; - -@end - -@implementation RNSUIBarButtonItem - -- (void)setMenuHidden:(BOOL)menuHidden -{ - _menuHidden = menuHidden; +@implementation RNSScreenStackHeaderConfig { +#ifndef RN_FABRIC_ENABLED + NSMutableArray *_reactSubviews; +#endif } -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_14_0) && \ - __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 -- (void)setMenu:(UIMenu *)menu +#ifdef RN_FABRIC_ENABLED +- (instancetype)initWithFrame:(CGRect)frame { - if (@available(iOS 14.0, *)) { - if (!_menuHidden) { - super.menu = menu; - } + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + self.hidden = YES; + _show = YES; + _translucent = NO; + _reactSubviews = [NSMutableArray new]; } + return self; } -#endif - -@end - -@implementation RNSScreenStackHeaderConfig { - NSMutableArray *_reactSubviews; -} - +#else - (instancetype)init { if (self = [super init]) { @@ -90,6 +95,7 @@ - (instancetype)init } return self; } +#endif - (void)insertReactSubview:(RNSScreenStackHeaderSubview *)subview atIndex:(NSInteger)atIndex { From 7548166536075b7707adabf9180b8de174598ef2 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 11:59:35 +0200 Subject: [PATCH 057/156] chore: merge props --- ios/RNSScreenStackHeaderConfig.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index af0cd724a3..dc7417e50a 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -67,7 +67,11 @@ - (void)reactSetFrame:(CGRect)frame @end @implementation RNSScreenStackHeaderConfig { -#ifndef RN_FABRIC_ENABLED +#ifdef RN_FABRIC_ENABLED + BOOL _initialPropsSet; + NSMutableArray *_reactSubviews; + facebook::react::SharedColor _backgroundSharedColor; +#else NSMutableArray *_reactSubviews; #endif } From 61edbe041a0f76b2df6651448021f887646ac4ef Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:03:39 +0200 Subject: [PATCH 058/156] chore: add pragma mark sections: Fabric specific, Paper specific --- ios/RNSScreenStackHeaderConfig.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index dc7417e50a..ec1e67d3dd 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -657,6 +657,10 @@ + (void)updateViewController:(UIViewController *)vc } } +#pragma mark - Fabric specific + +#pragma mark - Paper specific + @end @implementation RNSScreenStackHeaderConfigManager From ee4407ba8053b2bb33d0c5b8c1edccbec6220b02 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:12:44 +0200 Subject: [PATCH 059/156] chore: move subviews methods to paper specific sections --- ios/RNSScreenStackHeaderConfig.mm | 35 +++++++++++++++++-------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index ec1e67d3dd..e5bdf427bb 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -101,22 +101,7 @@ - (instancetype)init } #endif -- (void)insertReactSubview:(RNSScreenStackHeaderSubview *)subview atIndex:(NSInteger)atIndex -{ - [_reactSubviews insertObject:subview atIndex:atIndex]; - subview.reactSuperview = self; -} - -- (void)removeReactSubview:(RNSScreenStackHeaderSubview *)subview -{ - [_reactSubviews removeObject:subview]; -} - -- (NSArray *)reactSubviews -{ - return _reactSubviews; -} - +// done - (UIView *)reactSuperview { return _screenView; @@ -657,10 +642,28 @@ + (void)updateViewController:(UIViewController *)vc } } +#ifdef RN_FABRIC_ENABLED #pragma mark - Fabric specific +#else #pragma mark - Paper specific +- (void)insertReactSubview:(RNSScreenStackHeaderSubview *)subview atIndex:(NSInteger)atIndex +{ + [_reactSubviews insertObject:subview atIndex:atIndex]; + subview.reactSuperview = self; +} + +- (void)removeReactSubview:(RNSScreenStackHeaderSubview *)subview +{ + [_reactSubviews removeObject:subview]; +} + +- (NSArray *)reactSubviews +{ + return _reactSubviews; +} +#endif @end @implementation RNSScreenStackHeaderConfigManager From e30ade9944ac75db946194f5c4f5dd7fb2bd5625 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:14:27 +0200 Subject: [PATCH 060/156] chore: merge hitTest:withEvent: methods --- ios/RNSScreenStackHeaderConfig.mm | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index e5bdf427bb..ae8e4e178d 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -107,6 +107,7 @@ - (UIView *)reactSuperview return _screenView; } +// done - (void)removeFromSuperview { [super removeFromSuperview]; @@ -117,6 +118,23 @@ - (void)removeFromSuperview // is not added to native view hierarchy so we can apply our logic - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { +#ifdef RN_FABRIC_ENABLED + for (RNSScreenStackHeaderSubviewComponentView *subview in _reactSubviews) { + if (subview.type == facebook::react::RNSScreenStackHeaderSubviewType::Left || + subview.type == facebook::react::RNSScreenStackHeaderSubviewType::Right) { + // we wrap the headerLeft/Right component in a UIBarButtonItem + // so we need to use the only subview of it to retrieve the correct view + UIView *headerComponent = subview.subviews.firstObject; + // we convert the point to RNSScreenStackView since it always contains the header inside it + CGPoint convertedPoint = [_screenView.reactSuperview convertPoint:point toView:headerComponent]; + + UIView *hitTestResult = [headerComponent hitTest:convertedPoint withEvent:event]; + if (hitTestResult != nil) { + return hitTestResult; + } + } + } +#else for (RNSScreenStackHeaderSubview *subview in _reactSubviews) { if (subview.type == RNSScreenStackHeaderSubviewTypeLeft || subview.type == RNSScreenStackHeaderSubviewTypeRight) { // we wrap the headerLeft/Right component in a UIBarButtonItem @@ -131,6 +149,7 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event } } } +#endif return nil; } From 9ba8a2321ed916477d78a889d68a47de93530c61 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:18:25 +0200 Subject: [PATCH 061/156] chore: move didSetProps: method to paper specific section --- ios/RNSScreenStackHeaderConfig.mm | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index ae8e4e178d..17adae649a 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -114,6 +114,7 @@ - (void)removeFromSuperview _screenView = nil; } +// done // this method is never invoked by the system since this view // is not added to native view hierarchy so we can apply our logic - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event @@ -153,6 +154,7 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event return nil; } +// done - (void)updateViewControllerIfNeeded { UIViewController *vc = _screenView.controller; @@ -176,6 +178,7 @@ - (void)updateViewControllerIfNeeded } } +// done - (void)layoutNavigationControllerView { UIViewController *vc = _screenView.controller; @@ -183,18 +186,6 @@ - (void)layoutNavigationControllerView [navctr.view setNeedsLayout]; } -- (void)didSetProps:(NSArray *)changedProps -{ - [super didSetProps:changedProps]; - [self updateViewControllerIfNeeded]; - // We need to layout navigation controller view after translucent prop changes, because otherwise - // frame of RNSScreen will not be changed and screen content will remain the same size. - // For more details look at https://github.com/software-mansion/react-native-screens/issues/1158 - if ([changedProps containsObject:@"translucent"]) { - [self layoutNavigationControllerView]; - } -} - - (void)didUpdateReactSubviews { [super didUpdateReactSubviews]; @@ -682,6 +673,19 @@ - (void)removeReactSubview:(RNSScreenStackHeaderSubview *)subview { return _reactSubviews; } + +- (void)didSetProps:(NSArray *)changedProps +{ + [super didSetProps:changedProps]; + [self updateViewControllerIfNeeded]; + // We need to layout navigation controller view after translucent prop changes, because otherwise + // frame of RNSScreen will not be changed and screen content will remain the same size. + // For more details look at https://github.com/software-mansion/react-native-screens/issues/1158 + if ([changedProps containsObject:@"translucent"]) { + [self layoutNavigationControllerView]; + } +} + #endif @end From 888d5a70d72785447e3283b78446f0aaf28f5569 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:19:33 +0200 Subject: [PATCH 062/156] chore: move didUpdateReactSubviews to paper specific section --- ios/RNSScreenStackHeaderConfig.mm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 17adae649a..c05b4bacdf 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -186,12 +186,6 @@ - (void)layoutNavigationControllerView [navctr.view setNeedsLayout]; } -- (void)didUpdateReactSubviews -{ - [super didUpdateReactSubviews]; - [self updateViewControllerIfNeeded]; -} - + (void)setAnimatedConfig:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config { UINavigationBar *navbar = ((UINavigationController *)vc.parentViewController).navigationBar; @@ -686,6 +680,12 @@ - (void)didSetProps:(NSArray *)changedProps } } +- (void)didUpdateReactSubviews +{ + [super didUpdateReactSubviews]; + [self updateViewControllerIfNeeded]; +} + #endif @end From 8a15b87eb36606ff0d6dc9087f56bb4f752e1f14 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:23:12 +0200 Subject: [PATCH 063/156] chore: merge loadBackButtonImageInViewController methods --- ios/RNSScreenStackHeaderConfig.mm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index c05b4bacdf..8ef1aa345c 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -186,6 +186,7 @@ - (void)layoutNavigationControllerView [navctr.view setNeedsLayout]; } +// done + (void)setAnimatedConfig:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config { UINavigationBar *navbar = ((UINavigationController *)vc.parentViewController).navigationBar; @@ -281,6 +282,7 @@ + (void)setAnimatedConfig:(UIViewController *)vc withConfig:(RNSScreenStackHeade } } +// done + (void)setTitleAttibutes:(NSDictionary *)attrs forButton:(UIBarButtonItem *)button { [button setTitleTextAttributes:attrs forState:UIControlStateNormal]; @@ -290,8 +292,12 @@ + (void)setTitleAttibutes:(NSDictionary *)attrs forButton:(UIBarButtonItem *)but [button setTitleTextAttributes:attrs forState:UIControlStateFocused]; } +// done + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config { +#ifdef RN_FABRIC_ENABLED + @throw([NSException exceptionWithName:@"UNIMPLEMENTED" reason:@"Implement" userInfo:nil]); +#else BOOL hasBackButtonImage = NO; for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { if (subview.type == RNSScreenStackHeaderSubviewTypeBackButton && subview.subviews.count > 0) { @@ -358,6 +364,7 @@ + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc withConf } } } +#endif // RN_FABRIC_ENABLED return nil; } From 7aed355eedfe1443717387746fd98c9eb2ad836b Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:26:49 +0200 Subject: [PATCH 064/156] chore: merge buildAppearance:withConfig: methods --- ios/RNSScreenStackHeaderConfig.mm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 8ef1aa345c..dde44dd186 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -368,6 +368,7 @@ + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc withConf return nil; } +// done + (void)willShowViewController:(UIViewController *)vc animated:(BOOL)animated withConfig:(RNSScreenStackHeaderConfig *)config @@ -375,6 +376,7 @@ + (void)willShowViewController:(UIViewController *)vc [self updateViewController:vc withConfig:config animated:animated]; } +// done #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc @@ -394,9 +396,12 @@ + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc appearance.backgroundColor = config.backgroundColor; } + // TODO: implement blurEffect on Fabric +#ifndef RN_FABRIC_ENABLED if (config.blurEffect) { appearance.backgroundEffect = [UIBlurEffect effectWithStyle:config.blurEffect]; } +#endif if (config.hideShadow) { appearance.shadowColor = nil; @@ -452,12 +457,16 @@ + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc appearance.largeTitleTextAttributes = largeAttrs; } +#ifndef RN_FABRIC_ENABLED UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config]; if (backButtonImage) { [appearance setBackIndicatorImage:backButtonImage transitionMaskImage:backButtonImage]; } else if (appearance.backIndicatorImage) { [appearance setBackIndicatorImage:nil transitionMaskImage:nil]; } +#else + [appearance setBackIndicatorImage:nil transitionMaskImage:nil]; +#endif // RN_FABRIC_ENABLED return appearance; } #endif From 03121b0fe027aad0488884ca42975e29945be0a4 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:32:41 +0200 Subject: [PATCH 065/156] chore: merge updateViewController:withConfig:animated: methods --- ios/RNSScreenStackHeaderConfig.mm | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index dde44dd186..6cf4a15118 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -471,6 +471,7 @@ + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc } #endif +// done + (void)updateViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config animated:(BOOL)animated @@ -483,7 +484,11 @@ + (void)updateViewController:(UIViewController *)vc currentIndex > 0 ? [navctr.viewControllers objectAtIndex:currentIndex - 1].navigationItem : nil; BOOL wasHidden = navctr.navigationBarHidden; +#ifdef RN_FABRIC_ENABLED + BOOL shouldHide = config == nil || !config.show; +#else BOOL shouldHide = config == nil || config.hide; +#endif if (!shouldHide && !config.translucent) { // when nav bar is not translucent we chage edgesForExtendedLayout to avoid system laying out @@ -587,6 +592,39 @@ + (void)updateViewController:(UIViewController *)vc navitem.leftBarButtonItem = nil; navitem.rightBarButtonItem = nil; navitem.titleView = nil; +#ifdef RN_FABRIC_ENABLED + for (RNSScreenStackHeaderSubviewComponentView *subview in config.reactSubviews) { + switch (subview.type) { + case facebook::react::RNSScreenStackHeaderSubviewType::Left: { + //#if !TARGET_OS_TV + // navitem.leftItemsSupplementBackButton = config.backButtonInCustomView; + //#endif + UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; + navitem.leftBarButtonItem = buttonItem; + break; + } + case facebook::react::RNSScreenStackHeaderSubviewType::Right: { + UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; + navitem.rightBarButtonItem = buttonItem; + break; + } + case facebook::react::RNSScreenStackHeaderSubviewType::Center: + case facebook::react::RNSScreenStackHeaderSubviewType::Title: { + navitem.titleView = subview; + break; + } + case facebook::react::RNSScreenStackHeaderSubviewType::SearchBar: { + RCTLogWarn(@"SearchBar is not yet Fabric compatible in react-native-screens"); + break; + } + case facebook::react::RNSScreenStackHeaderSubviewType::Back: { + RCTLogWarn(@"Back button subivew is not yet Fabric compatible in react-native-screens"); + break; + ; + } + } + } +#else for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { switch (subview.type) { case RNSScreenStackHeaderSubviewTypeLeft: { @@ -630,6 +668,7 @@ + (void)updateViewController:(UIViewController *)vc } } } +#endif // RN_FABRIC_ENABLED if (animated && vc.transitionCoordinator != nil && vc.transitionCoordinator.presentationStyle == UIModalPresentationNone && !wasHidden) { From 7ba7feaf6e4a4685806b6c2767ad8997917b2d88 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:33:58 +0200 Subject: [PATCH 066/156] chore: move addSubviesToNavItem: method to Fabric specific section --- ios/RNSScreenStackHeaderConfig.mm | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 6cf4a15118..5f4e2be825 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -704,6 +704,36 @@ + (void)updateViewController:(UIViewController *)vc #ifdef RN_FABRIC_ENABLED #pragma mark - Fabric specific ++ (void)addSubviewsToNavItem:(UINavigationItem *)navitem withConfig:(RNSScreenStackHeaderConfig *)config +{ + for (RNSScreenStackHeaderSubviewComponentView *subview in config.reactSubviews) { + switch (subview.type) { + case facebook::react::RNSScreenStackHeaderSubviewType::Left: { + UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; + navitem.leftBarButtonItem = buttonItem; + break; + } + case facebook::react::RNSScreenStackHeaderSubviewType::Right: { + UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; + navitem.rightBarButtonItem = buttonItem; + break; + } + case facebook::react::RNSScreenStackHeaderSubviewType::Center: + case facebook::react::RNSScreenStackHeaderSubviewType::Title: { + navitem.titleView = subview; + break; + } + case facebook::react::RNSScreenStackHeaderSubviewType::SearchBar: { + RCTLogWarn(@"SearchBar is not yet supported in react-native-screens with Fabric enabled"); + break; + } + case facebook::react::RNSScreenStackHeaderSubviewType::Back: { + break; + } + } + } +} + #else #pragma mark - Paper specific From 36794a03ccec9e8d15ead1afc94e1e436fce57f5 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:35:59 +0200 Subject: [PATCH 067/156] chore: move mountChildComponentView method to Fabric specific section --- ios/RNSScreenStackHeaderConfig.mm | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 5f4e2be825..e5003c9508 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -734,6 +734,25 @@ + (void)addSubviewsToNavItem:(UINavigationItem *)navitem withConfig:(RNSScreenSt } } +- (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index +{ + if (![childComponentView isKindOfClass:[RNSScreenStackHeaderSubviewComponentView class]]) { + RCTLogError(@"ScreenStackHeader only accepts children of type ScreenStackHeaderSubview"); + return; + } + + RCTAssert( + childComponentView.superview == nil, + @"Attempt to mount already mounted component view. (parent: %@, child: %@, index: %@, existing parent: %@)", + self, + childComponentView, + @(index), + @([childComponentView.superview tag])); + + [_reactSubviews insertObject:(RNSScreenStackHeaderSubviewComponentView *)childComponentView atIndex:index]; + [self updateViewControllerIfNeeded]; +} + #else #pragma mark - Paper specific From 73f973ed538a4c6ce56042ef64cc54f780b48201 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:37:10 +0200 Subject: [PATCH 068/156] chore: move unmountChildComponentView: method to Fabric specific section --- ios/RNSScreenStackHeaderConfig.mm | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index e5003c9508..8b446f560b 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -753,6 +753,12 @@ - (void)mountChildComponentView:(UIView *)childCompone [self updateViewControllerIfNeeded]; } +- (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index +{ + [_reactSubviews removeObject:(RNSScreenStackHeaderSubviewComponentView *)childComponentView]; + [childComponentView removeFromSuperview]; +} + #else #pragma mark - Paper specific From 42b9d9def33a30899565fc11ea3217b40dd7cc16 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:39:57 +0200 Subject: [PATCH 069/156] chore: move RCTComponentViewProtocol methods & conversion methods to Fabric specific section --- ios/RNSScreenStackHeaderConfig.mm | 123 ++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 8b446f560b..61f6bb8a63 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -759,6 +759,122 @@ - (void)unmountChildComponentView:(UIView *)childCompo [childComponentView removeFromSuperview]; } +#pragma mark - RCTComponentViewProtocol + +- (void)prepareForRecycle +{ + [super prepareForRecycle]; + _initialPropsSet = NO; +} + ++ (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider +{ + return facebook::react::concreteComponentDescriptorProvider(); +} + +- (NSString *)getFontFamilyPropValue:(std::string)propValue +{ + if (propValue.length() > 0) { + return [[NSString alloc] initWithUTF8String:propValue.c_str()]; + } else { + return nil; + } +} + +- (NSString *)stringToPropValue:(std::string)value +{ + if (value.empty()) + return nil; + return [[NSString alloc] initWithUTF8String:value.c_str()]; +} + +- (NSNumber *)getFontSizePropValue:(int)value +{ + if (value > 0) + return [NSNumber numberWithInt:value]; + return nil; +} + +- (UISemanticContentAttribute)getDirectionPropValue:(facebook::react::RNSScreenStackHeaderConfigDirection)direction +{ + switch (direction) { + case facebook::react::RNSScreenStackHeaderConfigDirection::Rtl: + return UISemanticContentAttributeForceRightToLeft; + case facebook::react::RNSScreenStackHeaderConfigDirection::Ltr: + return UISemanticContentAttributeForceLeftToRight; + } +} + +- (void)updateProps:(facebook::react::Props::Shared const &)props oldProps:(facebook::react::Props::Shared const &)oldProps +{ + [super updateProps:props oldProps:oldProps]; + + const auto &oldScreenProps = *std::static_pointer_cast(_props); + const auto &newScreenProps = *std::static_pointer_cast(props); + + BOOL needsNavigationControllerLayout = !_initialPropsSet; + + if (newScreenProps.hidden != !_show) { + _show = !newScreenProps.hidden; + needsNavigationControllerLayout = YES; + } + + if (newScreenProps.translucent != _translucent) { + _translucent = newScreenProps.translucent; + needsNavigationControllerLayout = YES; + } + + _title = [self stringToPropValue:newScreenProps.title]; + if (newScreenProps.titleFontFamily != oldScreenProps.titleFontFamily) { + _titleFontFamily = [self getFontFamilyPropValue:newScreenProps.titleFontFamily]; + } + _titleFontWeight = [self stringToPropValue:newScreenProps.titleFontWeight]; + _titleFontSize = [self getFontSizePropValue:newScreenProps.titleFontSize]; + _hideShadow = newScreenProps.hideShadow; + + _largeTitle = newScreenProps.largeTitle; + if (newScreenProps.largeTitleFontFamily != oldScreenProps.largeTitleFontFamily) { + _largeTitleFontFamily = [self getFontFamilyPropValue:newScreenProps.largeTitleFontFamily]; + } + _largeTitleFontWeight = [self stringToPropValue:newScreenProps.largeTitleFontWeight]; + _largeTitleFontSize = [self getFontSizePropValue:newScreenProps.largeTitleFontSize]; + _largeTitleHideShadow = newScreenProps.largeTitleHideShadow; + + _backTitle = [self stringToPropValue:newScreenProps.backTitle]; + ; + if (newScreenProps.backTitleFontFamily != oldScreenProps.backTitleFontFamily) { + _backTitleFontFamily = [self getFontFamilyPropValue:newScreenProps.backTitleFontFamily]; + } + _backTitleFontSize = [self getFontSizePropValue:newScreenProps.backTitleFontSize]; + _hideBackButton = newScreenProps.hideBackButton; + _disableBackButtonMenu = newScreenProps.disableBackButtonMenu; + + if (newScreenProps.direction != oldScreenProps.direction) { + _direction = [self getDirectionPropValue:newScreenProps.direction]; + } + + // We cannot compare SharedColor because it is shared value. + // We could compare color value, but it is more performant to just assign new value + _titleColor = RCTUIColorFromSharedColor(newScreenProps.titleColor); + _largeTitleColor = RCTUIColorFromSharedColor(newScreenProps.largeTitleColor); + _color = RCTUIColorFromSharedColor(newScreenProps.color); + + if (_backgroundSharedColor != newScreenProps.backgroundColor) { + _backgroundSharedColor = newScreenProps.backgroundColor; + _backgroundColor = RCTUIColorFromSharedColor(_backgroundSharedColor); + } + + [self updateViewControllerIfNeeded]; + + if (needsNavigationControllerLayout) { + [self layoutNavigationControllerView]; + } + + _initialPropsSet = YES; + _props = std::static_pointer_cast(props); +} + + #else #pragma mark - Paper specific @@ -799,6 +915,13 @@ - (void)didUpdateReactSubviews #endif @end + +Class RNSScreenStackHeaderConfigCls(void) +{ + return RNSScreenStackHeaderConfig.class; +} + + @implementation RNSScreenStackHeaderConfigManager RCT_EXPORT_MODULE() From 92744dc9fec6bee97ab15965a0236e6e3018e3c5 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:42:22 +0200 Subject: [PATCH 070/156] fix: make implementations of StackHeaderConfigManager & StackheaderSubviewManager depend on RN_FABRIC_ENABLED --- ios/RNSScreenStackHeaderConfig.mm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 61f6bb8a63..2e9e8e95f6 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -921,7 +921,7 @@ - (void)didUpdateReactSubviews return RNSScreenStackHeaderConfig.class; } - +#ifndef RN_FABRIC_ENABLED @implementation RNSScreenStackHeaderConfigManager RCT_EXPORT_MODULE() @@ -959,6 +959,7 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(translucent, BOOL) @end +#endif // RN_FABRIC_ENABLED @implementation RCTConvert (RNSScreenStackHeader) @@ -1028,6 +1029,7 @@ + (NSMutableDictionary *)blurEffectsForIOSVersion @end +#ifndef RN_FABRIC_ENABLED @implementation RNSScreenStackHeaderSubviewManager RCT_EXPORT_MODULE() @@ -1040,3 +1042,4 @@ - (UIView *)view } @end +#endif // RN_FABRIC_ENABLED From b6ab6d2572d42a1eabf447b04e4e123bfdaa6be7 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:47:37 +0200 Subject: [PATCH 071/156] chore: remove RNSScreenStackHeaderConfigComponentView.{h,mm} files --- ios/RNSScreenStackHeaderConfigComponentView.h | 42 -- ...RNSScreenStackHeaderConfigComponentView.mm | 668 ------------------ 2 files changed, 710 deletions(-) delete mode 100644 ios/RNSScreenStackHeaderConfigComponentView.h delete mode 100644 ios/RNSScreenStackHeaderConfigComponentView.mm diff --git a/ios/RNSScreenStackHeaderConfigComponentView.h b/ios/RNSScreenStackHeaderConfigComponentView.h deleted file mode 100644 index 390023adc8..0000000000 --- a/ios/RNSScreenStackHeaderConfigComponentView.h +++ /dev/null @@ -1,42 +0,0 @@ -#import - -#import - -#import "RNSScreen.h" -#import "RNSScreenStackHeaderSubviewComponentView.h" - -@interface RNSScreenStackHeaderConfigComponentView : RCTViewComponentView - -@property (nonatomic, weak) RNSScreenView *screenView; -@property (nonatomic) NSMutableArray *reactSubviews; - -// Properties from props -@property (nonatomic) BOOL show; -@property (nonatomic) BOOL translucent; -@property (nonatomic) BOOL hideShadow; -@property (nonatomic, retain) NSString *title; -@property (nonatomic, retain) NSString *titleFontFamily; -@property (nonatomic, retain) NSNumber *titleFontSize; -@property (nonatomic, retain) NSString *titleFontWeight; -@property (nonatomic, retain) UIColor *titleColor; -@property (nonatomic) BOOL largeTitle; -@property (nonatomic, retain) NSString *largeTitleFontFamily; -@property (nonatomic, retain) NSNumber *largeTitleFontSize; -@property (nonatomic, retain) NSString *largeTitleFontWeight; -@property (nonatomic, retain) UIColor *largeTitleBackgroundColor; -@property (nonatomic) BOOL largeTitleHideShadow; -@property (nonatomic, retain) UIColor *largeTitleColor; -@property (nonatomic, retain) UIColor *backgroundColor; -@property (nonatomic, retain) UIColor *color; -@property (nonatomic) UISemanticContentAttribute direction; -@property (nonatomic, retain) NSString *backTitle; -@property (nonatomic, retain) NSString *backTitleFontFamily; -@property (nonatomic, retain) NSNumber *backTitleFontSize; -@property (nonatomic) BOOL disableBackButtonMenu; -@property (nonatomic) BOOL hideBackButton; - -+ (void)willShowViewController:(UIViewController *)vc - animated:(BOOL)animated - withConfig:(RNSScreenStackHeaderConfigComponentView *)config; - -@end diff --git a/ios/RNSScreenStackHeaderConfigComponentView.mm b/ios/RNSScreenStackHeaderConfigComponentView.mm deleted file mode 100644 index a0c06455f2..0000000000 --- a/ios/RNSScreenStackHeaderConfigComponentView.mm +++ /dev/null @@ -1,668 +0,0 @@ -#import "RNSScreenStackHeaderConfigComponentView.h" -#import "RNSScreenStackHeaderSubviewComponentView.h" - -#import "./utils/RNSUIBarButtonItem.h" - -#import -#import - -#import -#import -#import -#import - -#import - -#import "RCTFabricComponentsPlugins.h" - -using namespace facebook::react; - -@implementation RNSScreenStackHeaderConfigComponentView { - BOOL _initialPropsSet; - NSMutableArray *_reactSubviews; - SharedColor _backgroundSharedColor; -} - -- (instancetype)initWithFrame:(CGRect)frame -{ - if (self = [super initWithFrame:frame]) { - static const auto defaultProps = std::make_shared(); - _props = defaultProps; - self.hidden = YES; - _show = YES; - _translucent = NO; - _reactSubviews = [NSMutableArray new]; - } - - return self; -} - -- (UIView *)reactSuperview -{ - return _screenView; -} - -- (void)removeFromSuperview -{ - [super removeFromSuperview]; - _screenView = nil; -} - -// this method is never invoked by the system since this view -// is not added to native view hierarchy so we can apply our logic -- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event -{ - for (RNSScreenStackHeaderSubviewComponentView *subview in _reactSubviews) { - if (subview.type == facebook::react::RNSScreenStackHeaderSubviewType::Left || - subview.type == facebook::react::RNSScreenStackHeaderSubviewType::Right) { - // we wrap the headerLeft/Right component in a UIBarButtonItem - // so we need to use the only subview of it to retrieve the correct view - UIView *headerComponent = subview.subviews.firstObject; - // we convert the point to RNSScreenStackView since it always contains the header inside it - CGPoint convertedPoint = [_screenView.reactSuperview convertPoint:point toView:headerComponent]; - - UIView *hitTestResult = [headerComponent hitTest:convertedPoint withEvent:event]; - if (hitTestResult != nil) { - return hitTestResult; - } - } - } - return nil; -} - -- (void)updateViewControllerIfNeeded -{ - UIViewController *vc = _screenView.controller; - UINavigationController *nav = (UINavigationController *)vc.parentViewController; - UIViewController *nextVC = nav.visibleViewController; - if (nav.transitionCoordinator != nil) { - // if navigator is performing transition instead of allowing to update of `visibleConttroller` - // we look at `topController`. This is because during transitiong the `visibleController` won't - // point to the controller that is going to be revealed after transition. This check fixes the - // problem when config gets updated while the transition is ongoing. - nextVC = nav.topViewController; - } - - // we want updates sent to the VC below modal too since it is also visible - BOOL isPresentingVC = vc.presentedViewController == nextVC; - - BOOL isInFullScreenModal = nav == nil && _screenView.stackPresentation == RNSScreenStackPresentationFullScreenModal; - - // if nav is nil, it means we can be in a fullScreen modal, so there is no nextVC, but we still want to update - if (vc != nil && (nextVC == vc || isInFullScreenModal || isPresentingVC)) { - [RNSScreenStackHeaderConfigComponentView updateViewController:self.screenView.controller - withConfig:self - animated:YES]; - } -} - -- (void)layoutNavigationControllerView -{ - UIViewController *vc = _screenView.controller; - UINavigationController *navctr = vc.navigationController; - [navctr.view setNeedsLayout]; -} - -+ (void)setAnimatedConfig:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfigComponentView *)config -{ - UINavigationBar *navbar = ((UINavigationController *)vc.parentViewController).navigationBar; - // It is workaround for loading custom back icon when transitioning from a screen without header to the screen which - // has one. This action fails when navigating to the screen with header for the second time and loads default back - // button. It looks like changing the tint color of navbar triggers an update of the items belonging to it and it - // seems to load the custom back image so we change the tint color's alpha by a very small amount and then set it to - // the one it should have. -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_14_0) && \ - __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_14_0 - // it brakes the behavior of `headerRight` in iOS 14, where the bug desribed above seems to be fixed, so we do nothing - // in iOS 14 - if (@available(iOS 14.0, *)) { - } else -#endif - { - [navbar setTintColor:[config.color colorWithAlphaComponent:CGColorGetAlpha(config.color.CGColor) - 0.01]]; - } - [navbar setTintColor:config.color]; - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \ - __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 - if (@available(iOS 13.0, *)) { - // font customized on the navigation item level, so nothing to do here - } else -#endif - { - BOOL hideShadow = config.hideShadow; - - if (config.backgroundColor && CGColorGetAlpha(config.backgroundColor.CGColor) == 0.) { - [navbar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; - [navbar setBarTintColor:[UIColor clearColor]]; - hideShadow = YES; - } else { - [navbar setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault]; - [navbar setBarTintColor:config.backgroundColor]; - } - [navbar setTranslucent:config.translucent]; - [navbar setValue:@(hideShadow ? YES : NO) forKey:@"hidesShadow"]; - - if (config.titleFontFamily || config.titleFontSize || config.titleFontWeight || config.titleColor) { - NSMutableDictionary *attrs = [NSMutableDictionary new]; - - if (config.titleColor) { - attrs[NSForegroundColorAttributeName] = config.titleColor; - } - - NSString *family = config.titleFontFamily ?: nil; - NSNumber *size = config.titleFontSize ?: @17; - NSString *weight = config.titleFontWeight ?: nil; - if (family || weight) { - attrs[NSFontAttributeName] = [RCTFont updateFont:nil - withFamily:family - size:size - weight:weight - style:nil - variant:nil - scaleMultiplier:1.0]; - } else { - attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:[size floatValue]]; - } - [navbar setTitleTextAttributes:attrs]; - } - -#if !TARGET_OS_TV - if (@available(iOS 11.0, *)) { - if (config.largeTitle && - (config.largeTitleFontFamily || config.largeTitleFontSize || config.largeTitleFontWeight || - config.largeTitleColor || config.titleColor)) { - NSMutableDictionary *largeAttrs = [NSMutableDictionary new]; - if (config.largeTitleColor || config.titleColor) { - largeAttrs[NSForegroundColorAttributeName] = - config.largeTitleColor ? config.largeTitleColor : config.titleColor; - } - NSString *largeFamily = config.largeTitleFontFamily ?: nil; - NSNumber *largeSize = config.largeTitleFontSize ?: @34; - NSString *largeWeight = config.largeTitleFontWeight ?: nil; - if (largeFamily || largeWeight) { - largeAttrs[NSFontAttributeName] = [RCTFont updateFont:nil - withFamily:largeFamily - size:largeSize - weight:largeWeight - style:nil - variant:nil - scaleMultiplier:1.0]; - } else { - largeAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:[largeSize floatValue] weight:UIFontWeightBold]; - } - [navbar setLargeTitleTextAttributes:largeAttrs]; - } - } -#endif - } -} - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \ - __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 -+ (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc - withConfig:(RNSScreenStackHeaderConfigComponentView *)config - API_AVAILABLE(ios(13.0)) -{ - UINavigationBarAppearance *appearance = [UINavigationBarAppearance new]; - - if (config.backgroundColor && CGColorGetAlpha(config.backgroundColor.CGColor) == 0.) { - // transparent background color - [appearance configureWithTransparentBackground]; - } else { - [appearance configureWithOpaqueBackground]; - } - - // set background color if specified - if (config.backgroundColor) { - appearance.backgroundColor = config.backgroundColor; - } - - // if (config.blurEffect) { - // appearance.backgroundEffect = [UIBlurEffect effectWithStyle:config.blurEffect]; - // } - - if (config.hideShadow) { - appearance.shadowColor = nil; - } - - if (config.titleFontFamily || config.titleFontSize || config.titleFontWeight || config.titleColor) { - NSMutableDictionary *attrs = [NSMutableDictionary new]; - - if (config.titleColor) { - attrs[NSForegroundColorAttributeName] = config.titleColor; - } - - NSString *family = config.titleFontFamily ?: nil; - NSNumber *size = config.titleFontSize ?: @17; - NSString *weight = config.titleFontWeight ?: nil; - if (family || weight) { - attrs[NSFontAttributeName] = [RCTFont updateFont:nil - withFamily:config.titleFontFamily - size:size - weight:weight - style:nil - variant:nil - scaleMultiplier:1.0]; - } else { - attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:[size floatValue]]; - } - appearance.titleTextAttributes = attrs; - } - - if (config.largeTitleFontFamily || config.largeTitleFontSize || config.largeTitleFontWeight || - config.largeTitleColor || config.titleColor) { - NSMutableDictionary *largeAttrs = [NSMutableDictionary new]; - - if (config.largeTitleColor || config.titleColor) { - largeAttrs[NSForegroundColorAttributeName] = config.largeTitleColor ? config.largeTitleColor : config.titleColor; - } - - NSString *largeFamily = config.largeTitleFontFamily ?: nil; - NSNumber *largeSize = config.largeTitleFontSize ?: @34; - NSString *largeWeight = config.largeTitleFontWeight ?: nil; - if (largeFamily || largeWeight) { - largeAttrs[NSFontAttributeName] = [RCTFont updateFont:nil - withFamily:largeFamily - size:largeSize - weight:largeWeight - style:nil - variant:nil - scaleMultiplier:1.0]; - } else { - largeAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:[largeSize floatValue] weight:UIFontWeightBold]; - } - - appearance.largeTitleTextAttributes = largeAttrs; - } - - // UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config]; - // if (backButtonImage) { - // [appearance setBackIndicatorImage:backButtonImage transitionMaskImage:backButtonImage]; - // } else if (appearance.backIndicatorImage) { - [appearance setBackIndicatorImage:nil transitionMaskImage:nil]; - // } - return appearance; -} -#endif - -+ (void)willShowViewController:(UIViewController *)vc - animated:(BOOL)animated - withConfig:(RNSScreenStackHeaderConfigComponentView *)config -{ - [self updateViewController:vc withConfig:config animated:animated]; -} - -+ (void)setTitleAttibutes:(NSDictionary *)attrs forButton:(UIBarButtonItem *)button -{ - [button setTitleTextAttributes:attrs forState:UIControlStateNormal]; - [button setTitleTextAttributes:attrs forState:UIControlStateHighlighted]; - [button setTitleTextAttributes:attrs forState:UIControlStateDisabled]; - [button setTitleTextAttributes:attrs forState:UIControlStateSelected]; - [button setTitleTextAttributes:attrs forState:UIControlStateFocused]; -} - -+ (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc - withConfig:(RNSScreenStackHeaderConfigComponentView *)config -{ - @throw([NSException exceptionWithName:@"UNIMPLEMENTED" reason:@"Implement" userInfo:nil]); - return nil; -} - -+ (void)updateViewController:(UIViewController *)vc - withConfig:(RNSScreenStackHeaderConfigComponentView *)config - animated:(BOOL)animated -{ - UINavigationItem *navitem = vc.navigationItem; - UINavigationController *navctr = (UINavigationController *)vc.parentViewController; - - NSUInteger currentIndex = [navctr.viewControllers indexOfObject:vc]; - UINavigationItem *prevItem = - currentIndex > 0 ? [navctr.viewControllers objectAtIndex:currentIndex - 1].navigationItem : nil; - - BOOL wasHidden = navctr.navigationBarHidden; - BOOL shouldHide = config == nil || !config.show; - - if (!shouldHide && !config.translucent) { - // when nav bar is not translucent we chage edgesForExtendedLayout to avoid system laying out - // the screen underneath navigation controllers - vc.edgesForExtendedLayout = UIRectEdgeNone; - } else { - // system default is UIRectEdgeAll - vc.edgesForExtendedLayout = UIRectEdgeAll; - } - - [navctr setNavigationBarHidden:shouldHide animated:animated]; - - if ((config.direction == UISemanticContentAttributeForceLeftToRight || - config.direction == UISemanticContentAttributeForceRightToLeft) && - // iOS 12 cancels swipe gesture when direction is changed. See #1091 - navctr.view.semanticContentAttribute != config.direction) { - navctr.view.semanticContentAttribute = config.direction; - navctr.navigationBar.semanticContentAttribute = config.direction; - } - - if (shouldHide) { - return; - } - - navitem.title = config.title; -#if !TARGET_OS_TV - if (config.backTitle != nil || config.backTitleFontFamily || config.backTitleFontSize || - config.disableBackButtonMenu) { - RNSUIBarButtonItem *backBarButtonItem = [[RNSUIBarButtonItem alloc] initWithTitle:config.backTitle ?: prevItem.title - style:UIBarButtonItemStylePlain - target:nil - action:nil]; - - [backBarButtonItem setMenuHidden:config.disableBackButtonMenu]; - - prevItem.backBarButtonItem = backBarButtonItem; - if (config.backTitleFontFamily || config.backTitleFontSize) { - NSMutableDictionary *attrs = [NSMutableDictionary new]; - NSNumber *size = config.backTitleFontSize ?: @17; - if (config.backTitleFontFamily) { - attrs[NSFontAttributeName] = [RCTFont updateFont:nil - withFamily:config.backTitleFontFamily - size:size - weight:nil - style:nil - variant:nil - scaleMultiplier:1.0]; - } else { - attrs[NSFontAttributeName] = [UIFont boldSystemFontOfSize:[size floatValue]]; - } - [self setTitleAttibutes:attrs forButton:prevItem.backBarButtonItem]; - } - } else { - prevItem.backBarButtonItem = nil; - } - - if (@available(iOS 11.0, *)) { - if (config.largeTitle) { - navctr.navigationBar.prefersLargeTitles = YES; - } - navitem.largeTitleDisplayMode = - config.largeTitle ? UINavigationItemLargeTitleDisplayModeAlways : UINavigationItemLargeTitleDisplayModeNever; - } -#endif - -#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \ - __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 - if (@available(iOS 13.0, tvOS 13.0, *)) { - UINavigationBarAppearance *appearance = [self buildAppearance:vc withConfig:config]; - navitem.standardAppearance = appearance; - navitem.compactAppearance = appearance; - - UINavigationBarAppearance *scrollEdgeAppearance = - [[UINavigationBarAppearance alloc] initWithBarAppearance:appearance]; - if (config.largeTitleBackgroundColor != nil) { - scrollEdgeAppearance.backgroundColor = config.largeTitleBackgroundColor; - } - if (config.largeTitleHideShadow) { - scrollEdgeAppearance.shadowColor = nil; - } - navitem.scrollEdgeAppearance = scrollEdgeAppearance; - } else -#endif - { -#if !TARGET_OS_TV - // updating backIndicatotImage does not work when called during transition. On iOS pre 13 we need - // to update it before the navigation starts. - UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config]; - if (backButtonImage) { - navctr.navigationBar.backIndicatorImage = backButtonImage; - navctr.navigationBar.backIndicatorTransitionMaskImage = backButtonImage; - } else if (navctr.navigationBar.backIndicatorImage) { - navctr.navigationBar.backIndicatorImage = nil; - navctr.navigationBar.backIndicatorTransitionMaskImage = nil; - } -#endif - } -#if !TARGET_OS_TV - navitem.hidesBackButton = config.hideBackButton; -#endif - navitem.leftBarButtonItem = nil; - navitem.rightBarButtonItem = nil; - navitem.titleView = nil; - for (RNSScreenStackHeaderSubviewComponentView *subview in config.reactSubviews) { - switch (subview.type) { - case RNSScreenStackHeaderSubviewType::Left: { - //#if !TARGET_OS_TV - // navitem.leftItemsSupplementBackButton = config.backButtonInCustomView; - //#endif - UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; - navitem.leftBarButtonItem = buttonItem; - break; - } - case RNSScreenStackHeaderSubviewType::Right: { - UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; - navitem.rightBarButtonItem = buttonItem; - break; - } - case RNSScreenStackHeaderSubviewType::Center: - case RNSScreenStackHeaderSubviewType::Title: { - navitem.titleView = subview; - break; - } - case RNSScreenStackHeaderSubviewType::SearchBar: { - RCTLogWarn(@"SearchBar is not yet Fabric compatible in react-native-screens"); - break; - } - case RNSScreenStackHeaderSubviewType::Back: { - RCTLogWarn(@"Back button subivew is not yet Fabric compatible in react-native-screens"); - break; - ; - } - } - } - - if (animated && vc.transitionCoordinator != nil && - vc.transitionCoordinator.presentationStyle == UIModalPresentationNone && !wasHidden) { - // when there is an ongoing transition we may need to update navbar setting in animation block - // using animateAlongsideTransition. However, we only do that given the transition is not a modal - // transition (presentationStyle == UIModalPresentationNone) and that the bar was not previously - // hidden. This is because both for modal transitions and transitions from screen with hidden bar - // the transition animation block does not get triggered. This is ok, because with both of those - // types of transitions there is no "shared" navigation bar that needs to be updated in an animated - // way. - [vc.transitionCoordinator - animateAlongsideTransition:^(id _Nonnull context) { - [self setAnimatedConfig:vc withConfig:config]; - } - completion:^(id _Nonnull context) { - if ([context isCancelled]) { - UIViewController *fromVC = [context viewControllerForKey:UITransitionContextFromViewControllerKey]; - RNSScreenStackHeaderConfigComponentView *config = nil; - - // TODO: make sure this will exist in fabirc - for (UIView *subview in fromVC.view.reactSubviews) { - if ([subview isKindOfClass:[RNSScreenStackHeaderConfigComponentView class]]) { - config = (RNSScreenStackHeaderConfigComponentView *)subview; - break; - } - } - [self setAnimatedConfig:fromVC withConfig:config]; - } - }]; - } else { - [self setAnimatedConfig:vc withConfig:config]; - } -} - -+ (void)addSubviewsToNavItem:(UINavigationItem *)navitem withConfig:(RNSScreenStackHeaderConfigComponentView *)config -{ - for (RNSScreenStackHeaderSubviewComponentView *subview in config.reactSubviews) { - switch (subview.type) { - case facebook::react::RNSScreenStackHeaderSubviewType::Left: { - UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; - navitem.leftBarButtonItem = buttonItem; - break; - } - case facebook::react::RNSScreenStackHeaderSubviewType::Right: { - UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; - navitem.rightBarButtonItem = buttonItem; - break; - } - case facebook::react::RNSScreenStackHeaderSubviewType::Center: - case facebook::react::RNSScreenStackHeaderSubviewType::Title: { - navitem.titleView = subview; - break; - } - case facebook::react::RNSScreenStackHeaderSubviewType::SearchBar: { - RCTLogWarn(@"SearchBar is not yet supported in react-native-screens with Fabric enabled"); - break; - } - case facebook::react::RNSScreenStackHeaderSubviewType::Back: { - break; - } - } - } -} - -- (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index -{ - if (![childComponentView isKindOfClass:[RNSScreenStackHeaderSubviewComponentView class]]) { - RCTLogError(@"ScreenStackHeader only accepts children of type ScreenStackHeaderSubview"); - return; - } - - RCTAssert( - childComponentView.superview == nil, - @"Attempt to mount already mounted component view. (parent: %@, child: %@, index: %@, existing parent: %@)", - self, - childComponentView, - @(index), - @([childComponentView.superview tag])); - - [_reactSubviews insertObject:(RNSScreenStackHeaderSubviewComponentView *)childComponentView atIndex:index]; - [self updateViewControllerIfNeeded]; -} - -- (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index -{ - [_reactSubviews removeObject:(RNSScreenStackHeaderSubviewComponentView *)childComponentView]; - [childComponentView removeFromSuperview]; -} - -#pragma mark - RCTComponentViewProtocol - -- (void)prepareForRecycle -{ - [super prepareForRecycle]; - _initialPropsSet = NO; -} - -+ (ComponentDescriptorProvider)componentDescriptorProvider -{ - return concreteComponentDescriptorProvider(); -} - -- (NSString *)getFontFamilyPropValue:(std::string)propValue -{ - if (propValue.length() > 0) { - return [[NSString alloc] initWithUTF8String:propValue.c_str()]; - } else { - return nil; - } -} - -- (NSString *)stringToPropValue:(std::string)value -{ - if (value.empty()) - return nil; - return [[NSString alloc] initWithUTF8String:value.c_str()]; -} - -- (NSNumber *)getFontSizePropValue:(int)value -{ - if (value > 0) - return [NSNumber numberWithInt:value]; - return nil; -} - -- (UISemanticContentAttribute)getDirectionPropValue:(RNSScreenStackHeaderConfigDirection)direction -{ - switch (direction) { - case RNSScreenStackHeaderConfigDirection::Rtl: - return UISemanticContentAttributeForceRightToLeft; - case RNSScreenStackHeaderConfigDirection::Ltr: - return UISemanticContentAttributeForceLeftToRight; - } -} - -- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps -{ - [super updateProps:props oldProps:oldProps]; - - const auto &oldScreenProps = *std::static_pointer_cast(_props); - const auto &newScreenProps = *std::static_pointer_cast(props); - - BOOL needsNavigationControllerLayout = !_initialPropsSet; - - if (newScreenProps.hidden != !_show) { - _show = !newScreenProps.hidden; - needsNavigationControllerLayout = YES; - } - - if (newScreenProps.translucent != _translucent) { - _translucent = newScreenProps.translucent; - needsNavigationControllerLayout = YES; - } - - _title = [self stringToPropValue:newScreenProps.title]; - if (newScreenProps.titleFontFamily != oldScreenProps.titleFontFamily) { - _titleFontFamily = [self getFontFamilyPropValue:newScreenProps.titleFontFamily]; - } - _titleFontWeight = [self stringToPropValue:newScreenProps.titleFontWeight]; - _titleFontSize = [self getFontSizePropValue:newScreenProps.titleFontSize]; - _hideShadow = newScreenProps.hideShadow; - - _largeTitle = newScreenProps.largeTitle; - if (newScreenProps.largeTitleFontFamily != oldScreenProps.largeTitleFontFamily) { - _largeTitleFontFamily = [self getFontFamilyPropValue:newScreenProps.largeTitleFontFamily]; - } - _largeTitleFontWeight = [self stringToPropValue:newScreenProps.largeTitleFontWeight]; - _largeTitleFontSize = [self getFontSizePropValue:newScreenProps.largeTitleFontSize]; - _largeTitleHideShadow = newScreenProps.largeTitleHideShadow; - - _backTitle = [self stringToPropValue:newScreenProps.backTitle]; - ; - if (newScreenProps.backTitleFontFamily != oldScreenProps.backTitleFontFamily) { - _backTitleFontFamily = [self getFontFamilyPropValue:newScreenProps.backTitleFontFamily]; - } - _backTitleFontSize = [self getFontSizePropValue:newScreenProps.backTitleFontSize]; - _hideBackButton = newScreenProps.hideBackButton; - _disableBackButtonMenu = newScreenProps.disableBackButtonMenu; - - if (newScreenProps.direction != oldScreenProps.direction) { - _direction = [self getDirectionPropValue:newScreenProps.direction]; - } - - // We cannot compare SharedColor because it is shared value. - // We could compare color value, but it is more performant to just assign new value - _titleColor = RCTUIColorFromSharedColor(newScreenProps.titleColor); - _largeTitleColor = RCTUIColorFromSharedColor(newScreenProps.largeTitleColor); - _color = RCTUIColorFromSharedColor(newScreenProps.color); - - if (_backgroundSharedColor != newScreenProps.backgroundColor) { - _backgroundSharedColor = newScreenProps.backgroundColor; - _backgroundColor = RCTUIColorFromSharedColor(_backgroundSharedColor); - } - - [self updateViewControllerIfNeeded]; - - if (needsNavigationControllerLayout) { - [self layoutNavigationControllerView]; - } - - _initialPropsSet = YES; - _props = std::static_pointer_cast(props); -} - -@end - -Class RNSScreenStackHeaderConfigCls(void) -{ - return RNSScreenStackHeaderConfigComponentView.class; -} From ac1860239851f422b4190e23baae98008e26741b Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 12:52:51 +0200 Subject: [PATCH 072/156] refact: rename all references to RNSScreenStackHeaderComponentView --- ios/RNSScreen.mm | 9 ++++----- ios/RNSScreenStack.mm | 11 ++++------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 754a800d2b..4d86641b15 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -3,7 +3,6 @@ #import "RNSScreen.h" #import "RNSScreenContainer.h" #import "RNSScreenStack.h" -#import "RNSScreenStackHeaderConfig.h" #import "RNSScreenWindowTraits.h" #import @@ -16,11 +15,11 @@ #import #import #import "RNSConvert.h" -#import "RNSScreenStackHeaderConfigComponentView.h" #else #import #endif +#import "RNSScreenStackHeaderConfig.h" #import #import @@ -414,15 +413,15 @@ - (RCTTouchHandler *)touchHandler - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { [super mountChildComponentView:childComponentView index:index]; - if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfigComponentView class]]) { + if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfig class]]) { _config = childComponentView; - ((RNSScreenStackHeaderConfigComponentView *)childComponentView).screenView = self; + ((RNSScreenStackHeaderConfig *)childComponentView).screenView = self; } } - (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { - if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfigComponentView class]]) { + if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfig class]]) { _config = nil; } [super unmountChildComponentView:childComponentView index:index]; diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index e86e414bf0..77cb5f07a5 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -1,7 +1,4 @@ #ifdef RN_FABRIC_ENABLED -// TODO: merge this import when StackHeaderConfigComponentView is merged -#import "RNSScreenStackHeaderConfigComponentView.h" - #import #import @@ -14,7 +11,6 @@ #import #else -#import "RNSScreenStackHeaderConfig.h" #import #import @@ -28,6 +24,7 @@ #import "RNSScreenStack.h" #import "RNSScreenStackAnimator.h" #import "RNSScreenWindowTraits.h" +#import "RNSScreenStackHeaderConfig.h" @interface RNSScreenStackView () #ifdef RN_FABRIC_ENABLED @@ -165,9 +162,9 @@ - (void)navigationController:(UINavigationController *)navigationController // TODO: Improve this merge when StackHeaderConfig is merged #ifdef RN_FABRIC_ENABLED if ([view isKindOfClass:RNSScreenView.class]) { - RNSScreenStackHeaderConfigComponentView *config = - (RNSScreenStackHeaderConfigComponentView *)((RNSScreenView *)view).config; - [RNSScreenStackHeaderConfigComponentView willShowViewController:viewController animated:animated withConfig:config]; + RNSScreenStackHeaderConfig *config = + (RNSScreenStackHeaderConfig *)((RNSScreenView *)view).config; + [RNSScreenStackHeaderConfig willShowViewController:viewController animated:animated withConfig:config]; } #else RNSScreenStackHeaderConfig *config = nil; From c5238700ad50aaf9fe22c6bef3ea1654afc033a8 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 15:23:36 +0200 Subject: [PATCH 073/156] chore: restore NS_ASSUME_NONNULL_{BEGIN,END} macros --- ios/RNSScreen.h | 10 ++++++---- ios/RNSScreen.mm | 7 ++----- ios/RNSScreenContainer.h | 4 ++++ ios/RNSScreenStack.h | 4 ++++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/ios/RNSScreen.h b/ios/RNSScreen.h index 940cad393a..423732ff86 100644 --- a/ios/RNSScreen.h +++ b/ios/RNSScreen.h @@ -10,6 +10,8 @@ #import #endif +NS_ASSUME_NONNULL_BEGIN + @interface RCTConvert (RNSScreen) + (RNSScreenStackPresentation)RNSScreenStackPresentation:(id)json; @@ -101,14 +103,14 @@ @end -#ifdef RN_FABRIC_ENABLED - -#else +#ifndef RN_FABRIC_ENABLED @interface UIView (RNSScreen) - (UIViewController *)parentViewController; @end +#endif @interface RNSScreenManager : RCTViewManager @end -#endif + +NS_ASSUME_NONNULL_END diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 754a800d2b..001a4ed867 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -1196,13 +1196,11 @@ - (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingFor #endif // RN_FABRIC_ENABLED -#ifdef RN_FABRIC_ENABLED - -#else @implementation RNSScreenManager RCT_EXPORT_MODULE() +#ifndef RN_FABRIC_ENABLED // we want to handle the case when activityState is nil RCT_REMAP_VIEW_PROPERTY(activityState, activityStateOrNil, NSNumber) RCT_EXPORT_VIEW_PROPERTY(customAnimationOnSwipe, BOOL); @@ -1236,11 +1234,10 @@ - (UIView *)view { return [[RNSScreenView alloc] initWithBridge:self.bridge]; } +#endif // RN_FABRIC_ENABLED @end -#endif // RN_FABRIC_ENABLED - @implementation RCTConvert (RNSScreen) RCT_ENUM_CONVERTER( diff --git a/ios/RNSScreenContainer.h b/ios/RNSScreenContainer.h index 0493e81aa2..303110720f 100644 --- a/ios/RNSScreenContainer.h +++ b/ios/RNSScreenContainer.h @@ -1,5 +1,7 @@ #import +NS_ASSUME_NONNULL_BEGIN + @protocol RNSScreenContainerDelegate - (void)markChildUpdated; @@ -29,3 +31,5 @@ - (void)maybeDismissVC; @end + +NS_ASSUME_NONNULL_END diff --git a/ios/RNSScreenStack.h b/ios/RNSScreenStack.h index a383cd2265..62fbde928f 100644 --- a/ios/RNSScreenStack.h +++ b/ios/RNSScreenStack.h @@ -3,6 +3,8 @@ #import "RNSScreenContainer.h" +NS_ASSUME_NONNULL_BEGIN + @interface RNScreensNavigationController : UINavigationController @end @@ -19,3 +21,5 @@ @interface RNSScreenStackManager : RCTViewManager @end + +NS_ASSUME_NONNULL_END From bd737032a5c66ca787adfc750557a860520b4b11 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 15:24:21 +0200 Subject: [PATCH 074/156] refact: apply linter suggestions --- ios/RNSScreenStack.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index e1e3b62834..cf39b8a8d9 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -670,7 +670,7 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer [self cancelTouchesInParent]; return _controller.viewControllers.count >= 2; #endif - + #endif } From a0245cfd889729f43dc1109e935f1ecd97644c4a Mon Sep 17 00:00:00 2001 From: Wojciech Lewicki Date: Wed, 20 Apr 2022 15:25:36 +0200 Subject: [PATCH 075/156] fix: restore RNSScreenManager on Fabric --- FabricExample/ios/Podfile.lock | 2 +- ios/RNSScreen.h | 6 +----- ios/RNSScreen.mm | 35 ++++++++++++---------------------- 3 files changed, 14 insertions(+), 29 deletions(-) diff --git a/FabricExample/ios/Podfile.lock b/FabricExample/ios/Podfile.lock index 5c225fd1c0..5fa1f6c992 100644 --- a/FabricExample/ios/Podfile.lock +++ b/FabricExample/ios/Podfile.lock @@ -962,4 +962,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: d1692aab6ddf32b03dc03304e2dc04073ec65f35 -COCOAPODS: 1.11.3 +COCOAPODS: 1.11.2 diff --git a/ios/RNSScreen.h b/ios/RNSScreen.h index 940cad393a..eccbf8cc57 100644 --- a/ios/RNSScreen.h +++ b/ios/RNSScreen.h @@ -56,6 +56,7 @@ @property (nonatomic) RNSScreenSwipeDirection swipeDirection; @property (nonatomic) RNSScreenReplaceAnimation replaceAnimation; @property (nonatomic, retain) NSNumber *transitionDuration; +@property (nonatomic, readonly) BOOL dismissed; #if !TARGET_OS_TV @property (nonatomic) RNSStatusBarStyle statusBarStyle; @@ -80,7 +81,6 @@ @property (weak, nonatomic) UIView *reactSuperview; @property (nonatomic, retain) UIViewController *controller; -@property (nonatomic, readonly) BOOL dismissed; @property (nonatomic) int activityState; @property (nonatomic) BOOL preventNativeDismiss; @property (nonatomic) BOOL customAnimationOnSwipe; @@ -101,9 +101,6 @@ @end -#ifdef RN_FABRIC_ENABLED - -#else @interface UIView (RNSScreen) - (UIViewController *)parentViewController; @end @@ -111,4 +108,3 @@ @interface RNSScreenManager : RCTViewManager @end -#endif diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 754a800d2b..f5e3944ec2 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -40,41 +40,39 @@ @interface RNSScreenView () @implementation RNSScreenView { RNSScreen *_controller; + __weak RCTBridge *_bridge; #ifdef RN_FABRIC_ENABLED RCTSurfaceTouchHandler *_touchHandler; facebook::react::RNSScreenShadowNode::ConcreteState::Shared _state; #else - __weak RCTBridge *_bridge; RCTTouchHandler *_touchHandler; CGRect _reactFrame; #endif } -#ifdef RN_FABRIC_ENABLED - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { static const auto defaultProps = std::make_shared(); _props = defaultProps; - _controller = [[RNSScreen alloc] initWithView:self]; - // TODO: use default props (?) - _stackAnimation = RNSScreenStackAnimationDefault; - _stackPresentation = RNSScreenStackPresentationPush; - _hasStatusBarHiddenSet = NO; - _hasStatusBarStyleSet = NO; - _gestureEnabled = YES; - _hasStatusBarAnimationSet = NO; - _hasOrientationSet = NO; - _hasHomeIndicatorHiddenSet = NO; + [self initCommonProps]; } return self; } -#else + - (instancetype)initWithBridge:(RCTBridge *)bridge { if (self = [super init]) { _bridge = bridge; + [self initCommonProps]; + } + + return self; +} + +- (void)initCommonProps +{ _controller = [[RNSScreen alloc] initWithView:self]; _stackPresentation = RNSScreenStackPresentationPush; _stackAnimation = RNSScreenStackAnimationDefault; @@ -86,11 +84,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge _hasStatusBarHiddenSet = NO; _hasOrientationSet = NO; _hasHomeIndicatorHiddenSet = NO; - } - - return self; } -#endif - (UIViewController *)reactViewController { @@ -259,6 +253,7 @@ - (void)addSubview:(UIView *)view - (void)notifyDismissedWithCount:(int)dismissCount { + _dismissed = YES; #ifdef RN_FABRIC_ENABLED // If screen is already unmounted then there will be no event emitter // it will be cleaned in prepareForRecycle @@ -267,7 +262,6 @@ - (void)notifyDismissedWithCount:(int)dismissCount ->onDismissed(facebook::react::RNSScreenEventEmitter::OnDismissed{dismissCount : dismissCount}); } #else - _dismissed = YES; if (self.onDismissed) { dispatch_async(dispatch_get_main_queue(), ^{ if (self.onDismissed) { @@ -1196,9 +1190,6 @@ - (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingFor #endif // RN_FABRIC_ENABLED -#ifdef RN_FABRIC_ENABLED - -#else @implementation RNSScreenManager RCT_EXPORT_MODULE() @@ -1239,8 +1230,6 @@ - (UIView *)view @end -#endif // RN_FABRIC_ENABLED - @implementation RCTConvert (RNSScreen) RCT_ENUM_CONVERTER( From 57554c9bb8c99d3791c7a457a2d6077fbb8923f7 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 15:42:04 +0200 Subject: [PATCH 076/156] refact: apply linter suggestion --- ios/RNSScreen.mm | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 7bd60c121c..94cecdc93b 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -73,17 +73,17 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge - (void)initCommonProps { - _controller = [[RNSScreen alloc] initWithView:self]; - _stackPresentation = RNSScreenStackPresentationPush; - _stackAnimation = RNSScreenStackAnimationDefault; - _gestureEnabled = YES; - _replaceAnimation = RNSScreenReplaceAnimationPop; - _dismissed = NO; - _hasStatusBarStyleSet = NO; - _hasStatusBarAnimationSet = NO; - _hasStatusBarHiddenSet = NO; - _hasOrientationSet = NO; - _hasHomeIndicatorHiddenSet = NO; + _controller = [[RNSScreen alloc] initWithView:self]; + _stackPresentation = RNSScreenStackPresentationPush; + _stackAnimation = RNSScreenStackAnimationDefault; + _gestureEnabled = YES; + _replaceAnimation = RNSScreenReplaceAnimationPop; + _dismissed = NO; + _hasStatusBarStyleSet = NO; + _hasStatusBarAnimationSet = NO; + _hasStatusBarHiddenSet = NO; + _hasOrientationSet = NO; + _hasHomeIndicatorHiddenSet = NO; } - (UIViewController *)reactViewController From 0e73f8f08d37aad3ca0f7192ba2f10061e143981 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 16:05:23 +0200 Subject: [PATCH 077/156] fix: remove merge artifact --- ios/RNSScreen.h | 2 -- ios/RNSScreen.mm | 2 -- 2 files changed, 4 deletions(-) diff --git a/ios/RNSScreen.h b/ios/RNSScreen.h index f50f01632b..265854039f 100644 --- a/ios/RNSScreen.h +++ b/ios/RNSScreen.h @@ -103,11 +103,9 @@ NS_ASSUME_NONNULL_BEGIN @end -#ifndef RN_FABRIC_ENABLED @interface UIView (RNSScreen) - (UIViewController *)parentViewController; @end -#endif @interface RNSScreenManager : RCTViewManager diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 94cecdc93b..e64e3a8587 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -1194,7 +1194,6 @@ @implementation RNSScreenManager RCT_EXPORT_MODULE() -#ifndef RN_FABRIC_ENABLED // we want to handle the case when activityState is nil RCT_REMAP_VIEW_PROPERTY(activityState, activityStateOrNil, NSNumber) RCT_EXPORT_VIEW_PROPERTY(customAnimationOnSwipe, BOOL); @@ -1228,7 +1227,6 @@ - (UIView *)view { return [[RNSScreenView alloc] initWithBridge:self.bridge]; } -#endif // RN_FABRIC_ENABLED @end From f47cf9a7938cc827e7ce8eb9d2926bc8c62dd45c Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 20 Apr 2022 16:12:56 +0200 Subject: [PATCH 078/156] refact: apply linter suggestions --- ios/RNSScreenStack.mm | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 32721a8a37..e86e414bf0 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -24,30 +24,27 @@ #import #endif // RN_FABRIC_ENABLED -#import "RNSScreenStack.h" #import "RNSScreen.h" +#import "RNSScreenStack.h" #import "RNSScreenStackAnimator.h" #import "RNSScreenWindowTraits.h" @interface RNSScreenStackView () #ifdef RN_FABRIC_ENABLED -< - UINavigationControllerDelegate, - UIAdaptivePresentationControllerDelegate, - UIGestureRecognizerDelegate, - UIViewControllerTransitioningDelegate, - RCTMountingTransactionObserving> { + { BOOL _updateScheduled; } #else -< - UINavigationControllerDelegate, - UIAdaptivePresentationControllerDelegate, - UIGestureRecognizerDelegate, - UIViewControllerTransitioningDelegate> + #endif - @property (nonatomic) NSMutableArray *presentedModals; @property (nonatomic) BOOL updatingModals; @property (nonatomic) BOOL scheduleModalsUpdate; @@ -354,7 +351,7 @@ - (void)setModalViewControllers:(NSArray *)controllers __weak RNSScreenStackView *weakSelf = self; void (^afterTransitions)(void) = ^{ - // TODO: Implement onFinishTransitioning on Fabric + // TODO: Implement onFinishTransitioning on Fabric #ifndef RN_FABRIC_ENABLED if (weakSelf.onFinishTransitioning) { weakSelf.onFinishTransitioning(nil); @@ -742,7 +739,6 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer #endif } - #if !TARGET_OS_TV // done - (void)setupGestureHandlers From f1e9b9d773a2ec993fcb8fe00961ac0dd99c5f44 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 08:10:45 +0200 Subject: [PATCH 079/156] fix: add *.mm sources to TestExample project --- RNScreens.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RNScreens.podspec b/RNScreens.podspec index fd93a55dcb..c722d9548e 100644 --- a/RNScreens.podspec +++ b/RNScreens.podspec @@ -47,7 +47,7 @@ Pod::Spec.new do |s| ss.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/common/cpp\"" } end else - s.source_files = "ios/**/*.{h,m}" + s.source_files = "ios/**/*.{h,m,mm}" s.requires_arc = true s.dependency "React-Core" From d447b7f9211c89c0b3eaaef5ccc674414a1ede00 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 08:26:24 +0200 Subject: [PATCH 080/156] refact: apply linter suggestions --- ios/RNSScreen.mm | 2 +- ios/RNSScreenStack.mm | 5 ++--- ios/RNSScreenStackHeaderConfig.mm | 28 ++++++++++++++-------------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 983d325dd9..22e3f2af16 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -19,9 +19,9 @@ #import #endif -#import "RNSScreenStackHeaderConfig.h" #import #import +#import "RNSScreenStackHeaderConfig.h" #import #import "RCTFabricComponentsPlugins.h" diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 77cb5f07a5..006ae2c986 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -23,8 +23,8 @@ #import "RNSScreen.h" #import "RNSScreenStack.h" #import "RNSScreenStackAnimator.h" -#import "RNSScreenWindowTraits.h" #import "RNSScreenStackHeaderConfig.h" +#import "RNSScreenWindowTraits.h" @interface RNSScreenStackView () #ifdef RN_FABRIC_ENABLED @@ -162,8 +162,7 @@ - (void)navigationController:(UINavigationController *)navigationController // TODO: Improve this merge when StackHeaderConfig is merged #ifdef RN_FABRIC_ENABLED if ([view isKindOfClass:RNSScreenView.class]) { - RNSScreenStackHeaderConfig *config = - (RNSScreenStackHeaderConfig *)((RNSScreenView *)view).config; + RNSScreenStackHeaderConfig *config = (RNSScreenStackHeaderConfig *)((RNSScreenView *)view).config; [RNSScreenStackHeaderConfig willShowViewController:viewController animated:animated withConfig:config]; } #else diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 2e9e8e95f6..14972e7a9f 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -1,16 +1,15 @@ #ifdef RN_FABRIC_ENABLED -#import "RNSScreenStackHeaderSubviewComponentView.h" -#import "RCTFabricComponentsPlugins.h" +#import +#import #import #import #import #import #import -#import -#import +#import "RCTFabricComponentsPlugins.h" +#import "RNSScreenStackHeaderSubviewComponentView.h" #else // TODO: move this import when SearchBar is implemented on Fabric -#import "RNSSearchBar.h" #import #import #import @@ -19,11 +18,11 @@ #import #import #import +#import "RNSSearchBar.h" #endif -#import "RNSScreenStackHeaderConfig.h" -#import "RNSScreen.h" #import "./utils/RNSUIBarButtonItem.h" - +#import "RNSScreen.h" +#import "RNSScreenStackHeaderConfig.h" #ifndef RN_FABRIC_ENABLED // Some RN private method hacking below. Couldn't figure out better way to access image data @@ -296,7 +295,7 @@ + (void)setTitleAttibutes:(NSDictionary *)attrs forButton:(UIBarButtonItem *)but + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config { #ifdef RN_FABRIC_ENABLED - @throw([NSException exceptionWithName:@"UNIMPLEMENTED" reason:@"Implement" userInfo:nil]); + @throw([NSException exceptionWithName:@"UNIMPLEMENTED" reason:@"Implement" userInfo:nil]); #else BOOL hasBackButtonImage = NO; for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { @@ -769,7 +768,8 @@ - (void)prepareForRecycle + (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider { - return facebook::react::concreteComponentDescriptorProvider(); + return facebook::react::concreteComponentDescriptorProvider< + facebook::react::RNSScreenStackHeaderConfigComponentDescriptor>(); } - (NSString *)getFontFamilyPropValue:(std::string)propValue @@ -805,11 +805,13 @@ - (UISemanticContentAttribute)getDirectionPropValue:(facebook::react::RNSScreenS } } -- (void)updateProps:(facebook::react::Props::Shared const &)props oldProps:(facebook::react::Props::Shared const &)oldProps +- (void)updateProps:(facebook::react::Props::Shared const &)props + oldProps:(facebook::react::Props::Shared const &)oldProps { [super updateProps:props oldProps:oldProps]; - const auto &oldScreenProps = *std::static_pointer_cast(_props); + const auto &oldScreenProps = + *std::static_pointer_cast(_props); const auto &newScreenProps = *std::static_pointer_cast(props); BOOL needsNavigationControllerLayout = !_initialPropsSet; @@ -874,7 +876,6 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props oldProps:(face _props = std::static_pointer_cast(props); } - #else #pragma mark - Paper specific @@ -915,7 +916,6 @@ - (void)didUpdateReactSubviews #endif @end - Class RNSScreenStackHeaderConfigCls(void) { return RNSScreenStackHeaderConfig.class; From cddd893b74f8256d28b141ffad7d7ead63102e90 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 08:41:10 +0200 Subject: [PATCH 081/156] chore: create separate file for RNSScreenStackHeaderSubview --- ios/RNSScreenStackHeaderSubview.h | 0 ios/RNSScreenStackHeaderSubview.mm | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 ios/RNSScreenStackHeaderSubview.h create mode 100644 ios/RNSScreenStackHeaderSubview.mm diff --git a/ios/RNSScreenStackHeaderSubview.h b/ios/RNSScreenStackHeaderSubview.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ios/RNSScreenStackHeaderSubview.mm b/ios/RNSScreenStackHeaderSubview.mm new file mode 100644 index 0000000000..e69de29bb2 From 3f0482aa7178a17ebece93c6679231b90e0e21ab Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 08:48:40 +0200 Subject: [PATCH 082/156] chore: remove RNSScreenStackHeaderSubviewComponentView.h --- ios/RNSScreenStackHeaderSubviewComponentView.h | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 ios/RNSScreenStackHeaderSubviewComponentView.h diff --git a/ios/RNSScreenStackHeaderSubviewComponentView.h b/ios/RNSScreenStackHeaderSubviewComponentView.h deleted file mode 100644 index eaaa920f91..0000000000 --- a/ios/RNSScreenStackHeaderSubviewComponentView.h +++ /dev/null @@ -1,14 +0,0 @@ -#import - -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface RNSScreenStackHeaderSubviewComponentView : RCTViewComponentView - -@property (nonatomic) facebook::react::RNSScreenStackHeaderSubviewType type; - -@end - -NS_ASSUME_NONNULL_END From 2bfa48570feb895af67a7358aebc13b60e3f75af Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 08:56:12 +0200 Subject: [PATCH 083/156] chore: initial setup for ScreenStackHeaderSubview --- ios/RNSScreenStackHeaderConfig.h | 19 +------------- ios/RNSScreenStackHeaderConfig.mm | 10 -------- ios/RNSScreenStackHeaderSubview.h | 41 +++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h index 7ecad53f9e..3e97b7648a 100644 --- a/ios/RNSScreenStackHeaderConfig.h +++ b/ios/RNSScreenStackHeaderConfig.h @@ -1,7 +1,6 @@ #ifdef RN_FABRIC_ENABLED #import #import -#import "RNSScreenStackHeaderSubviewComponentView.h" #else #import // TODO: move this import when SearchBar is implemented on Fabric @@ -10,6 +9,7 @@ #import #import "RNSScreen.h" +#import "RNSScreenStackHeaderSubview.h" @interface RNSScreenStackHeaderConfig : #ifdef RN_FABRIC_ENABLED @@ -65,15 +65,6 @@ @end #endif -typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) { - RNSScreenStackHeaderSubviewTypeBackButton, - RNSScreenStackHeaderSubviewTypeLeft, - RNSScreenStackHeaderSubviewTypeRight, - RNSScreenStackHeaderSubviewTypeTitle, - RNSScreenStackHeaderSubviewTypeCenter, - RNSScreenStackHeaderSubviewTypeSearchBar, -}; - @interface RCTConvert (RNSScreenStackHeader) + (RNSScreenStackHeaderSubviewType)RNSScreenStackHeaderSubviewType:(id)json; @@ -81,11 +72,3 @@ typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) { + (UISemanticContentAttribute)UISemanticContentAttribute:(id)json; @end - -#ifndef RN_FABRIC_ENABLED -@interface RNSScreenStackHeaderSubviewManager : RCTViewManager - -@property (nonatomic) RNSScreenStackHeaderSubviewType type; - -@end -#endif diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 14972e7a9f..1894f113b3 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -36,16 +36,6 @@ @interface RCTImageLoader (Private) @end #endif -@interface RNSScreenStackHeaderSubview : UIView - -@property (nonatomic, weak) RCTBridge *bridge; -@property (nonatomic, weak) UIView *reactSuperview; -@property (nonatomic) RNSScreenStackHeaderSubviewType type; - -- (instancetype)initWithBridge:(RCTBridge *)bridge; - -@end - @implementation RNSScreenStackHeaderSubview - (instancetype)initWithBridge:(RCTBridge *)bridge diff --git a/ios/RNSScreenStackHeaderSubview.h b/ios/RNSScreenStackHeaderSubview.h index e69de29bb2..9b111eb7d1 100644 --- a/ios/RNSScreenStackHeaderSubview.h +++ b/ios/RNSScreenStackHeaderSubview.h @@ -0,0 +1,41 @@ +#import + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface RNSScreenStackHeaderSubview : +#ifdef RN_FABRIC_ENABLED + RCTViewComponentView +#else + UIView +#endif + +#ifdef RN_FABRIC_ENABLED +@property (nonatomic) facebook::react::RNSScreenStackHeaderSubviewType type; +#else +@property (nonatomic, weak) RCTBridge *bridge; // TODO: consider moving this to paper only section +@property (nonatomic, weak) UIView *reactSuperview; +@property (nonatomic) RNSScreenStackHeaderSubviewType type; + +- (instancetype)initWithBridge:(RCTBridge *)bridge; // TODO: consider moving this to paper only section +#endif +@end + +@interface RNSScreenStackHeaderSubviewManager : RCTViewManager + +@property (nonatomic) RNSScreenStackHeaderSubviewType type; + +@end + +typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) { + RNSScreenStackHeaderSubviewTypeBackButton, + RNSScreenStackHeaderSubviewTypeLeft, + RNSScreenStackHeaderSubviewTypeRight, + RNSScreenStackHeaderSubviewTypeTitle, + RNSScreenStackHeaderSubviewTypeCenter, + RNSScreenStackHeaderSubviewTypeSearchBar, +}; + +NS_ASSUME_NONNULL_END From b1dbf4d87237775b30af5353e2f3e09c58e735e9 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 08:57:20 +0200 Subject: [PATCH 084/156] refact: change reference to ScreenStackHeaderSubview in HeaderConfig --- ios/RNSScreenStackHeaderConfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h index 3e97b7648a..23c76aa1a3 100644 --- a/ios/RNSScreenStackHeaderConfig.h +++ b/ios/RNSScreenStackHeaderConfig.h @@ -22,7 +22,7 @@ #ifdef RN_FABRIC_ENABLED // TODO: change type when StackHeaderSubview is merged (??) -@property (nonatomic) NSMutableArray *reactSubviews; +@property (nonatomic) NSMutableArray *reactSubviews; @property (nonatomic) BOOL show; #else @property (nonatomic) UIBlurEffectStyle blurEffect; From d6c89b52cf1717bdc29b2287551b392a8e4b2bce Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 09:03:55 +0200 Subject: [PATCH 085/156] refact: rename references to RNSScreenStackHeaderSubviewComponentView --- ios/RNSScreenStackHeaderConfig.mm | 34 +++++++------------------------ 1 file changed, 7 insertions(+), 27 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 1894f113b3..d6633100b4 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -7,7 +7,6 @@ #import #import #import "RCTFabricComponentsPlugins.h" -#import "RNSScreenStackHeaderSubviewComponentView.h" #else // TODO: move this import when SearchBar is implemented on Fabric #import @@ -36,32 +35,13 @@ @interface RCTImageLoader (Private) @end #endif -@implementation RNSScreenStackHeaderSubview - -- (instancetype)initWithBridge:(RCTBridge *)bridge -{ - if (self = [super init]) { - _bridge = bridge; - } - return self; -} - -- (void)reactSetFrame:(CGRect)frame -{ - // Block any attempt to set coordinates on RNSScreenStackHeaderSubview. This - // makes UINavigationBar the only one to control the position of header content. - [super reactSetFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; -} - -@end @implementation RNSScreenStackHeaderConfig { + NSMutableArray *_reactSubviews; #ifdef RN_FABRIC_ENABLED BOOL _initialPropsSet; - NSMutableArray *_reactSubviews; facebook::react::SharedColor _backgroundSharedColor; #else - NSMutableArray *_reactSubviews; #endif } @@ -109,7 +89,7 @@ - (void)removeFromSuperview - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { #ifdef RN_FABRIC_ENABLED - for (RNSScreenStackHeaderSubviewComponentView *subview in _reactSubviews) { + for (RNSScreenStackHeaderSubview *subview in _reactSubviews) { if (subview.type == facebook::react::RNSScreenStackHeaderSubviewType::Left || subview.type == facebook::react::RNSScreenStackHeaderSubviewType::Right) { // we wrap the headerLeft/Right component in a UIBarButtonItem @@ -582,7 +562,7 @@ + (void)updateViewController:(UIViewController *)vc navitem.rightBarButtonItem = nil; navitem.titleView = nil; #ifdef RN_FABRIC_ENABLED - for (RNSScreenStackHeaderSubviewComponentView *subview in config.reactSubviews) { + for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { switch (subview.type) { case facebook::react::RNSScreenStackHeaderSubviewType::Left: { //#if !TARGET_OS_TV @@ -695,7 +675,7 @@ + (void)updateViewController:(UIViewController *)vc + (void)addSubviewsToNavItem:(UINavigationItem *)navitem withConfig:(RNSScreenStackHeaderConfig *)config { - for (RNSScreenStackHeaderSubviewComponentView *subview in config.reactSubviews) { + for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { switch (subview.type) { case facebook::react::RNSScreenStackHeaderSubviewType::Left: { UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; @@ -725,7 +705,7 @@ + (void)addSubviewsToNavItem:(UINavigationItem *)navitem withConfig:(RNSScreenSt - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { - if (![childComponentView isKindOfClass:[RNSScreenStackHeaderSubviewComponentView class]]) { + if (![childComponentView isKindOfClass:[RNSScreenStackHeaderSubview class]]) { RCTLogError(@"ScreenStackHeader only accepts children of type ScreenStackHeaderSubview"); return; } @@ -738,13 +718,13 @@ - (void)mountChildComponentView:(UIView *)childCompone @(index), @([childComponentView.superview tag])); - [_reactSubviews insertObject:(RNSScreenStackHeaderSubviewComponentView *)childComponentView atIndex:index]; + [_reactSubviews insertObject:(RNSScreenStackHeaderSubview *)childComponentView atIndex:index]; [self updateViewControllerIfNeeded]; } - (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { - [_reactSubviews removeObject:(RNSScreenStackHeaderSubviewComponentView *)childComponentView]; + [_reactSubviews removeObject:(RNSScreenStackHeaderSubview *)childComponentView]; [childComponentView removeFromSuperview]; } From de9da1c3b52e4c9f51954bb02d1aff7b6c77683b Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 09:04:06 +0200 Subject: [PATCH 086/156] chore: move paper class implementation to new file --- ios/RNSScreenStackHeaderSubview.mm | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ios/RNSScreenStackHeaderSubview.mm b/ios/RNSScreenStackHeaderSubview.mm index e69de29bb2..ee8eb98a46 100644 --- a/ios/RNSScreenStackHeaderSubview.mm +++ b/ios/RNSScreenStackHeaderSubview.mm @@ -0,0 +1,20 @@ +#import "RNSScreenStackHeaderSubview.h" + +@implementation RNSScreenStackHeaderSubview + +- (instancetype)initWithBridge:(RCTBridge *)bridge +{ + if (self = [super init]) { + _bridge = bridge; + } + return self; +} + +- (void)reactSetFrame:(CGRect)frame +{ + // Block any attempt to set coordinates on RNSScreenStackHeaderSubview. This + // makes UINavigationBar the only one to control the position of header content. + [super reactSetFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; +} + +@end From 22d1e35646f4c572bf28a2de08e0fd77d339c787 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 09:11:16 +0200 Subject: [PATCH 087/156] chore: move RNSScreenStackHeaderSubviewType enum to RNSEnums & add conversion method --- ios/RNSConvert.h | 3 +++ ios/RNSConvert.mm | 18 ++++++++++++++++++ ios/RNSEnums.h | 9 +++++++++ ios/RNSScreenStackHeaderSubview.h | 10 +--------- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/ios/RNSConvert.h b/ios/RNSConvert.h index 2bb24c9503..82650edcce 100644 --- a/ios/RNSConvert.h +++ b/ios/RNSConvert.h @@ -12,6 +12,9 @@ + (RNSScreenStackAnimation)RNSScreenStackAnimationFromCppEquivalent: (facebook::react::RNSScreenStackAnimation)stackAnimation; ++ (RNSScreenStackHeaderSubviewType)RNSScreenStackHeaderSubviewTypeFromCppEquivalent: + (facebook::react::RNSScreenStackHeaderSubviewType)subviewType; + @end #endif /* RNSConvert_h */ diff --git a/ios/RNSConvert.mm b/ios/RNSConvert.mm index 8db9635408..c87788c33a 100644 --- a/ios/RNSConvert.mm +++ b/ios/RNSConvert.mm @@ -47,4 +47,22 @@ + (RNSScreenStackAnimation)RNSScreenStackAnimationFromCppEquivalent: } } ++ (RNSScreenStackHeaderSubviewType)RNSScreenStackHeaderSubviewTypeFromCppEquivalent: + (facebook::react::RNSScreenStackHeaderSubviewType)subviewType +{ + switch (subviewType) { + case facebook::react::RNSScreenStackHeaderSubviewType::Left: + return RNSScreenStackHeaderSubviewTypeLeft; + case facebook::react::RNSScreenStackHeaderSubviewType::Right: + return RNSScreenStackHeaderSubviewTypeRight; + case facebook::react::RNSScreenStackHeaderSubviewType::Title: + return RNSScreenStackHeaderSubviewTypeTitle; + case facebook::react::RNSScreenStackHeaderSubviewType::Center: + return RNSScreenStackHeaderSubviewTypeCenter; + case facebook::react::RNSScreenStackHeaderSubviewType::SearchBar: + return RNSScreenStackHeaderSubviewTypeSearchBar; + case facebook::react::RNSScreenStackHeaderSubviewType::Back: + return RNSScreenStackHeaderSubviewTypeBackButton; + } +} @end diff --git a/ios/RNSEnums.h b/ios/RNSEnums.h index 4009a8e0a0..62288753bf 100644 --- a/ios/RNSEnums.h +++ b/ios/RNSEnums.h @@ -52,4 +52,13 @@ typedef NS_ENUM(NSInteger, RNSWindowTrait) { RNSWindowTraitHomeIndicatorHidden, }; +typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) { + RNSScreenStackHeaderSubviewTypeBackButton, + RNSScreenStackHeaderSubviewTypeLeft, + RNSScreenStackHeaderSubviewTypeRight, + RNSScreenStackHeaderSubviewTypeTitle, + RNSScreenStackHeaderSubviewTypeCenter, + RNSScreenStackHeaderSubviewTypeSearchBar, +}; + #endif /* RNSEnums_h */ diff --git a/ios/RNSScreenStackHeaderSubview.h b/ios/RNSScreenStackHeaderSubview.h index 9b111eb7d1..e112a5fcca 100644 --- a/ios/RNSScreenStackHeaderSubview.h +++ b/ios/RNSScreenStackHeaderSubview.h @@ -2,6 +2,7 @@ #import #import +#import "RNSEnums.h" NS_ASSUME_NONNULL_BEGIN @@ -29,13 +30,4 @@ NS_ASSUME_NONNULL_BEGIN @end -typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) { - RNSScreenStackHeaderSubviewTypeBackButton, - RNSScreenStackHeaderSubviewTypeLeft, - RNSScreenStackHeaderSubviewTypeRight, - RNSScreenStackHeaderSubviewTypeTitle, - RNSScreenStackHeaderSubviewTypeCenter, - RNSScreenStackHeaderSubviewTypeSearchBar, -}; - NS_ASSUME_NONNULL_END From 0f9fb7e19a88191f0651b768f6448550153652de Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 09:12:15 +0200 Subject: [PATCH 088/156] refact: apply linter suggestions --- ios/RNSScreenStackHeaderConfig.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index d6633100b4..14daf894dc 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -35,7 +35,6 @@ @interface RCTImageLoader (Private) @end #endif - @implementation RNSScreenStackHeaderConfig { NSMutableArray *_reactSubviews; #ifdef RN_FABRIC_ENABLED From ff59d49c1218bccaf393a6fa6c429ed62affa519 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 09:17:56 +0200 Subject: [PATCH 089/156] fix: add missing header --- ios/RNSScreenStackHeaderSubview.h | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/RNSScreenStackHeaderSubview.h b/ios/RNSScreenStackHeaderSubview.h index e112a5fcca..290c8edd39 100644 --- a/ios/RNSScreenStackHeaderSubview.h +++ b/ios/RNSScreenStackHeaderSubview.h @@ -1,6 +1,7 @@ #import #import +#import #import #import "RNSEnums.h" From 82868d1363f657b352009c5325cf358cc0ee84c0 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 09:20:46 +0200 Subject: [PATCH 090/156] chore: organize imports in header file --- ios/RNSScreenStackHeaderSubview.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ios/RNSScreenStackHeaderSubview.h b/ios/RNSScreenStackHeaderSubview.h index 290c8edd39..2c58fd4819 100644 --- a/ios/RNSScreenStackHeaderSubview.h +++ b/ios/RNSScreenStackHeaderSubview.h @@ -1,8 +1,11 @@ -#import +#ifdef RN_FABRIC_ENABLED #import -#import +#import #import +#endif + +#import #import "RNSEnums.h" NS_ASSUME_NONNULL_BEGIN From cbd8540e2421303156c0b92a736ea6883868bc80 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 09:50:08 +0200 Subject: [PATCH 091/156] chore: merge implementations --- ios/RNSScreenStackHeaderConfig.h | 1 - ios/RNSScreenStackHeaderConfig.mm | 28 ------- ios/RNSScreenStackHeaderSubview.h | 19 +++-- ios/RNSScreenStackHeaderSubview.mm | 117 ++++++++++++++++++++++++++++- 4 files changed, 129 insertions(+), 36 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h index 23c76aa1a3..36ee195798 100644 --- a/ios/RNSScreenStackHeaderConfig.h +++ b/ios/RNSScreenStackHeaderConfig.h @@ -67,7 +67,6 @@ @interface RCTConvert (RNSScreenStackHeader) -+ (RNSScreenStackHeaderSubviewType)RNSScreenStackHeaderSubviewType:(id)json; + (UIBlurEffectStyle)UIBlurEffectStyle:(id)json; + (UISemanticContentAttribute)UISemanticContentAttribute:(id)json; diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 14daf894dc..86d5ed59a4 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -972,19 +972,6 @@ + (NSMutableDictionary *)blurEffectsForIOSVersion return blurEffects; } -RCT_ENUM_CONVERTER( - RNSScreenStackHeaderSubviewType, - (@{ - @"back" : @(RNSScreenStackHeaderSubviewTypeBackButton), - @"left" : @(RNSScreenStackHeaderSubviewTypeLeft), - @"right" : @(RNSScreenStackHeaderSubviewTypeRight), - @"title" : @(RNSScreenStackHeaderSubviewTypeTitle), - @"center" : @(RNSScreenStackHeaderSubviewTypeCenter), - @"searchBar" : @(RNSScreenStackHeaderSubviewTypeSearchBar), - }), - RNSScreenStackHeaderSubviewTypeTitle, - integerValue) - RCT_ENUM_CONVERTER( UISemanticContentAttribute, (@{ @@ -997,18 +984,3 @@ + (NSMutableDictionary *)blurEffectsForIOSVersion RCT_ENUM_CONVERTER(UIBlurEffectStyle, ([self blurEffectsForIOSVersion]), UIBlurEffectStyleExtraLight, integerValue) @end - -#ifndef RN_FABRIC_ENABLED -@implementation RNSScreenStackHeaderSubviewManager - -RCT_EXPORT_MODULE() - -RCT_EXPORT_VIEW_PROPERTY(type, RNSScreenStackHeaderSubviewType) - -- (UIView *)view -{ - return [[RNSScreenStackHeaderSubview alloc] initWithBridge:self.bridge]; -} - -@end -#endif // RN_FABRIC_ENABLED diff --git a/ios/RNSScreenStackHeaderSubview.h b/ios/RNSScreenStackHeaderSubview.h index 2c58fd4819..05cb22758c 100644 --- a/ios/RNSScreenStackHeaderSubview.h +++ b/ios/RNSScreenStackHeaderSubview.h @@ -5,6 +5,7 @@ #import #endif +#import #import #import "RNSEnums.h" @@ -17,15 +18,15 @@ NS_ASSUME_NONNULL_BEGIN UIView #endif -#ifdef RN_FABRIC_ENABLED -@property (nonatomic) facebook::react::RNSScreenStackHeaderSubviewType type; -#else -@property (nonatomic, weak) RCTBridge *bridge; // TODO: consider moving this to paper only section -@property (nonatomic, weak) UIView *reactSuperview; @property (nonatomic) RNSScreenStackHeaderSubviewType type; - +@property (nonatomic, weak) RCTBridge *bridge; // TODO: consider moving this to paper only section - (instancetype)initWithBridge:(RCTBridge *)bridge; // TODO: consider moving this to paper only section + // right now it is possible to call this code in Fabric impl + +#ifndef RN_FABRIC_ENABLED +@property (nonatomic, weak) UIView *reactSuperview; #endif + @end @interface RNSScreenStackHeaderSubviewManager : RCTViewManager @@ -34,4 +35,10 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface RCTConvert (RNSScreenStackHeaderSubview) + ++ (RNSScreenStackHeaderSubviewType)RNSScreenStackHeaderSubviewType:(id)json; + +@end + NS_ASSUME_NONNULL_END diff --git a/ios/RNSScreenStackHeaderSubview.mm b/ios/RNSScreenStackHeaderSubview.mm index ee8eb98a46..304671ad96 100644 --- a/ios/RNSScreenStackHeaderSubview.mm +++ b/ios/RNSScreenStackHeaderSubview.mm @@ -1,6 +1,22 @@ #import "RNSScreenStackHeaderSubview.h" +#import "RNSConvert.h" -@implementation RNSScreenStackHeaderSubview +#ifdef RN_FABRIC_ENABLED +#import +#import +#import + +#import "RCTFabricComponentsPlugins.h" +#import +#endif + +@implementation RNSScreenStackHeaderSubview { +#ifdef RN_FABRIC_ENABLED + BOOL _isInitialValueSet; +#endif +} + +#pragma mark - Common - (instancetype)initWithBridge:(RCTBridge *)bridge { @@ -10,6 +26,68 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge return self; } +#ifdef RN_FABRIC_ENABLED + +#pragma mark - Fabric specific + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + static const auto defaultProps = std::make_shared(); + _props = defaultProps; + } + + return self; +} + +#pragma mark - RCTComponentViewProtocol + +- (void)prepareForRecycle +{ + [super prepareForRecycle]; + _isInitialValueSet = NO; +} + +- (void)updateProps:(facebook::react::Props::Shared const &)props oldProps:(facebook::react::Props::Shared const &)oldProps +{ + const auto &newHeaderSubviewProps = *std::static_pointer_cast(props); + const auto &oldHeaderSubviewProps = *std::static_pointer_cast(_props); + + if (newHeaderSubviewProps.type != oldHeaderSubviewProps.type) { + _type = [RNSConvert RNSScreenStackHeaderSubviewTypeFromCppEquivalent:newHeaderSubviewProps.type]; + _isInitialValueSet = YES; + } + + [super updateProps:props oldProps:oldProps]; +} + ++ (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider +{ + return facebook::react::concreteComponentDescriptorProvider(); +} + +- (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics + oldLayoutMetrics:(const facebook::react::LayoutMetrics &)oldLayoutMetrics +{ + CGRect frame = RCTCGRectFromRect(layoutMetrics.frame); + // CALayer will crash if we pass NaN or Inf values. + // It's unclear how to detect this case on cross-platform manner holistically, so we have to do it on the mounting + // layer as well. NaN/Inf is a kinda valid result of some math operations. Even if we can (and should) detect (and + // report early) incorrect (NaN and Inf) values which come from JavaScript side, we sometimes cannot backtrace the + // sources of a calculation that produced an incorrect/useless result. + if (!std::isfinite(frame.size.width) || !std::isfinite(frame.size.height)) { + RCTLogWarn( + @"-[UIView(ComponentViewProtocol) updateLayoutMetrics:oldLayoutMetrics:]: Received invalid layout metrics (%@) for a view (%@).", + NSStringFromCGRect(frame), + self); + } else { + self.bounds = CGRect{CGPointZero, frame.size}; + } +} + +#else +#pragma mark - Paper specific + - (void)reactSetFrame:(CGRect)frame { // Block any attempt to set coordinates on RNSScreenStackHeaderSubview. This @@ -17,4 +95,41 @@ - (void)reactSetFrame:(CGRect)frame [super reactSetFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)]; } +#endif // RN_FABRIC_ENABLED +@end + +@implementation RNSScreenStackHeaderSubviewManager + +RCT_EXPORT_MODULE() + +RCT_EXPORT_VIEW_PROPERTY(type, RNSScreenStackHeaderSubviewType) + +- (UIView *)view +{ + return [[RNSScreenStackHeaderSubview alloc] initWithBridge:self.bridge]; +} + @end + +Class RNSScreenStackHeaderSubviewCls(void) +{ + return RNSScreenStackHeaderSubview.class; +} + +@implementation RCTConvert (RNSScreenStackHeaderSubview) + +RCT_ENUM_CONVERTER( + RNSScreenStackHeaderSubviewType, + (@{ + @"back" : @(RNSScreenStackHeaderSubviewTypeBackButton), + @"left" : @(RNSScreenStackHeaderSubviewTypeLeft), + @"right" : @(RNSScreenStackHeaderSubviewTypeRight), + @"title" : @(RNSScreenStackHeaderSubviewTypeTitle), + @"center" : @(RNSScreenStackHeaderSubviewTypeCenter), + @"searchBar" : @(RNSScreenStackHeaderSubviewTypeSearchBar), + }), + RNSScreenStackHeaderSubviewTypeTitle, + integerValue) + +@end + From 6322a023ff0bd23f95b417f391a04585599a3842 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 09:50:41 +0200 Subject: [PATCH 092/156] refact: apply linter suggestions --- ios/RNSScreenStackHeaderSubview.mm | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/ios/RNSScreenStackHeaderSubview.mm b/ios/RNSScreenStackHeaderSubview.mm index 304671ad96..98e37abd11 100644 --- a/ios/RNSScreenStackHeaderSubview.mm +++ b/ios/RNSScreenStackHeaderSubview.mm @@ -6,8 +6,8 @@ #import #import -#import "RCTFabricComponentsPlugins.h" #import +#import "RCTFabricComponentsPlugins.h" #endif @implementation RNSScreenStackHeaderSubview { @@ -48,11 +48,14 @@ - (void)prepareForRecycle _isInitialValueSet = NO; } -- (void)updateProps:(facebook::react::Props::Shared const &)props oldProps:(facebook::react::Props::Shared const &)oldProps +- (void)updateProps:(facebook::react::Props::Shared const &)props + oldProps:(facebook::react::Props::Shared const &)oldProps { - const auto &newHeaderSubviewProps = *std::static_pointer_cast(props); - const auto &oldHeaderSubviewProps = *std::static_pointer_cast(_props); - + const auto &newHeaderSubviewProps = + *std::static_pointer_cast(props); + const auto &oldHeaderSubviewProps = + *std::static_pointer_cast(_props); + if (newHeaderSubviewProps.type != oldHeaderSubviewProps.type) { _type = [RNSConvert RNSScreenStackHeaderSubviewTypeFromCppEquivalent:newHeaderSubviewProps.type]; _isInitialValueSet = YES; @@ -63,7 +66,8 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props oldProps:(face + (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider { - return facebook::react::concreteComponentDescriptorProvider(); + return facebook::react::concreteComponentDescriptorProvider< + facebook::react::RNSScreenStackHeaderSubviewComponentDescriptor>(); } - (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics @@ -132,4 +136,3 @@ @implementation RCTConvert (RNSScreenStackHeaderSubview) integerValue) @end - From 6690ba641891ab637eb53a5e396d5e630bacefa0 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 09:51:48 +0200 Subject: [PATCH 093/156] chore: remove RNSScreenStackHeaderSubviewComponentView.mm file --- ...NSScreenStackHeaderSubviewComponentView.mm | 77 ------------------- 1 file changed, 77 deletions(-) delete mode 100644 ios/RNSScreenStackHeaderSubviewComponentView.mm diff --git a/ios/RNSScreenStackHeaderSubviewComponentView.mm b/ios/RNSScreenStackHeaderSubviewComponentView.mm deleted file mode 100644 index bad3ecc3fd..0000000000 --- a/ios/RNSScreenStackHeaderSubviewComponentView.mm +++ /dev/null @@ -1,77 +0,0 @@ -#import "RNSScreenStackHeaderSubviewComponentView.h" - -#import - -#import -#import -#import - -#import "RCTFabricComponentsPlugins.h" - -using namespace facebook::react; - -@implementation RNSScreenStackHeaderSubviewComponentView { - BOOL _isInitialValueSet; - RNSScreenStackHeaderSubviewType _type; -} - -- (instancetype)initWithFrame:(CGRect)frame -{ - if (self = [super initWithFrame:frame]) { - static const auto defaultProps = std::make_shared(); - _props = defaultProps; - } - - return self; -} - -- (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics - oldLayoutMetrics:(const facebook::react::LayoutMetrics &)oldLayoutMetrics -{ - CGRect frame = RCTCGRectFromRect(layoutMetrics.frame); - // CALayer will crash if we pass NaN or Inf values. - // It's unclear how to detect this case on cross-platform manner holistically, so we have to do it on the mounting - // layer as well. NaN/Inf is a kinda valid result of some math operations. Even if we can (and should) detect (and - // report early) incorrect (NaN and Inf) values which come from JavaScript side, we sometimes cannot backtrace the - // sources of a calculation that produced an incorrect/useless result. - if (!std::isfinite(frame.size.width) || !std::isfinite(frame.size.height)) { - RCTLogWarn( - @"-[UIView(ComponentViewProtocol) updateLayoutMetrics:oldLayoutMetrics:]: Received invalid layout metrics (%@) for a view (%@).", - NSStringFromCGRect(frame), - self); - } else { - self.bounds = CGRect{CGPointZero, frame.size}; - } -} - -#pragma mark - RCTComponentViewProtocol - -- (void)prepareForRecycle -{ - [super prepareForRecycle]; - _isInitialValueSet = NO; -} - -- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps -{ - const auto &newHeaderSubviewProps = *std::static_pointer_cast(props); - - if (_type != newHeaderSubviewProps.type) { - _type = newHeaderSubviewProps.type; - _isInitialValueSet = YES; - } - - [super updateProps:props oldProps:oldProps]; -} - -+ (ComponentDescriptorProvider)componentDescriptorProvider -{ - return concreteComponentDescriptorProvider(); -} - -@end - -Class RNSScreenStackHeaderSubviewCls(void) -{ - return RNSScreenStackHeaderSubviewComponentView.class; -} From 076be9854f6a946232d8704aff8bc79f6862a335 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 09:56:25 +0200 Subject: [PATCH 094/156] chore: merge RNSScreenStackHeaderConfig#hitTest:withEvent: method impls --- ios/RNSScreenStackHeaderConfig.mm | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 86d5ed59a4..cc0787b0b3 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -87,23 +87,6 @@ - (void)removeFromSuperview // is not added to native view hierarchy so we can apply our logic - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { -#ifdef RN_FABRIC_ENABLED - for (RNSScreenStackHeaderSubview *subview in _reactSubviews) { - if (subview.type == facebook::react::RNSScreenStackHeaderSubviewType::Left || - subview.type == facebook::react::RNSScreenStackHeaderSubviewType::Right) { - // we wrap the headerLeft/Right component in a UIBarButtonItem - // so we need to use the only subview of it to retrieve the correct view - UIView *headerComponent = subview.subviews.firstObject; - // we convert the point to RNSScreenStackView since it always contains the header inside it - CGPoint convertedPoint = [_screenView.reactSuperview convertPoint:point toView:headerComponent]; - - UIView *hitTestResult = [headerComponent hitTest:convertedPoint withEvent:event]; - if (hitTestResult != nil) { - return hitTestResult; - } - } - } -#else for (RNSScreenStackHeaderSubview *subview in _reactSubviews) { if (subview.type == RNSScreenStackHeaderSubviewTypeLeft || subview.type == RNSScreenStackHeaderSubviewTypeRight) { // we wrap the headerLeft/Right component in a UIBarButtonItem @@ -118,7 +101,6 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event } } } -#endif return nil; } From d3c9e6cb0246040379b210a7430724bc512bdf65 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 10:05:28 +0200 Subject: [PATCH 095/156] chore: merge RNSScreenStackHeaderConfig#updateViewController:withConfig:animated: method --- ios/RNSScreenStackHeaderConfig.mm | 47 ++++++++----------------------- 1 file changed, 12 insertions(+), 35 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index cc0787b0b3..75bad9c3ef 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -421,7 +421,6 @@ + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc } #endif -// done + (void)updateViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config animated:(BOOL)animated @@ -542,45 +541,14 @@ + (void)updateViewController:(UIViewController *)vc navitem.leftBarButtonItem = nil; navitem.rightBarButtonItem = nil; navitem.titleView = nil; -#ifdef RN_FABRIC_ENABLED - for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { - switch (subview.type) { - case facebook::react::RNSScreenStackHeaderSubviewType::Left: { - //#if !TARGET_OS_TV - // navitem.leftItemsSupplementBackButton = config.backButtonInCustomView; - //#endif - UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; - navitem.leftBarButtonItem = buttonItem; - break; - } - case facebook::react::RNSScreenStackHeaderSubviewType::Right: { - UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; - navitem.rightBarButtonItem = buttonItem; - break; - } - case facebook::react::RNSScreenStackHeaderSubviewType::Center: - case facebook::react::RNSScreenStackHeaderSubviewType::Title: { - navitem.titleView = subview; - break; - } - case facebook::react::RNSScreenStackHeaderSubviewType::SearchBar: { - RCTLogWarn(@"SearchBar is not yet Fabric compatible in react-native-screens"); - break; - } - case facebook::react::RNSScreenStackHeaderSubviewType::Back: { - RCTLogWarn(@"Back button subivew is not yet Fabric compatible in react-native-screens"); - break; - ; - } - } - } -#else for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { switch (subview.type) { case RNSScreenStackHeaderSubviewTypeLeft: { +#ifndef RN_FABRIC_ENABLED #if !TARGET_OS_TV navitem.leftItemsSupplementBackButton = config.backButtonInCustomView; #endif +#endif // RN_FABRIC_ENABLED UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; navitem.leftBarButtonItem = buttonItem; break; @@ -596,6 +564,9 @@ + (void)updateViewController:(UIViewController *)vc break; } case RNSScreenStackHeaderSubviewTypeSearchBar: { +#ifdef RN_FABRIC_ENABLED + RCTLogWarn(@"SearchBar is not yet Fabric compatible in react-native-screens"); +#else if (subview.subviews == nil || [subview.subviews count] == 0) { RCTLogWarn( @"Failed to attach search bar to the header. We recommend using `useLayoutEffect` when managing " @@ -612,13 +583,19 @@ + (void)updateViewController:(UIViewController *)vc } #endif } + +#endif // RN_FABRIC_ENABLED + break; } case RNSScreenStackHeaderSubviewTypeBackButton: { +#ifdef RN_FABRIC_ENABLED + RCTLogWarn(@"Back button subivew is not yet Fabric compatible in react-native-screens"); +#endif break; + ; } } } -#endif // RN_FABRIC_ENABLED if (animated && vc.transitionCoordinator != nil && vc.transitionCoordinator.presentationStyle == UIModalPresentationNone && !wasHidden) { From 466056e631e51bb0f2ce53ec0966a7c11ac4a2eb Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 10:07:19 +0200 Subject: [PATCH 096/156] fix: update enums in RNSScreenStackHeaderConfig --- ios/RNSScreenStackHeaderConfig.mm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 75bad9c3ef..d5d3b40203 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -635,26 +635,26 @@ + (void)addSubviewsToNavItem:(UINavigationItem *)navitem withConfig:(RNSScreenSt { for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { switch (subview.type) { - case facebook::react::RNSScreenStackHeaderSubviewType::Left: { + case RNSScreenStackHeaderSubviewTypeLeft: { UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; navitem.leftBarButtonItem = buttonItem; break; } - case facebook::react::RNSScreenStackHeaderSubviewType::Right: { + case RNSScreenStackHeaderSubviewTypeRight: { UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; navitem.rightBarButtonItem = buttonItem; break; } - case facebook::react::RNSScreenStackHeaderSubviewType::Center: - case facebook::react::RNSScreenStackHeaderSubviewType::Title: { + case RNSScreenStackHeaderSubviewTypeCenter: + case RNSScreenStackHeaderSubviewTypeTitle: { navitem.titleView = subview; break; } - case facebook::react::RNSScreenStackHeaderSubviewType::SearchBar: { + case RNSScreenStackHeaderSubviewTypeSearchBar: { RCTLogWarn(@"SearchBar is not yet supported in react-native-screens with Fabric enabled"); break; } - case facebook::react::RNSScreenStackHeaderSubviewType::Back: { + case RNSScreenStackHeaderSubviewTypeBackButton: { break; } } From fa8d395b84c449a44ba745559bd06998f938fe04 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 10:17:16 +0200 Subject: [PATCH 097/156] fix: restore RNSScreenStackHeaderConfigManager for Fabric impl --- ios/RNSScreenStackHeaderConfig.h | 2 -- ios/RNSScreenStackHeaderConfig.mm | 2 -- 2 files changed, 4 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h index 7ecad53f9e..a1f5b109ed 100644 --- a/ios/RNSScreenStackHeaderConfig.h +++ b/ios/RNSScreenStackHeaderConfig.h @@ -59,11 +59,9 @@ @end -#ifndef RN_FABRIC_ENABLED @interface RNSScreenStackHeaderConfigManager : RCTViewManager @end -#endif typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) { RNSScreenStackHeaderSubviewTypeBackButton, diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 14972e7a9f..874ae17231 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -921,7 +921,6 @@ - (void)didUpdateReactSubviews return RNSScreenStackHeaderConfig.class; } -#ifndef RN_FABRIC_ENABLED @implementation RNSScreenStackHeaderConfigManager RCT_EXPORT_MODULE() @@ -959,7 +958,6 @@ - (UIView *)view RCT_EXPORT_VIEW_PROPERTY(translucent, BOOL) @end -#endif // RN_FABRIC_ENABLED @implementation RCTConvert (RNSScreenStackHeader) From 5d2b1fb95e3552e994891eeec121395408467d57 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 10:23:44 +0200 Subject: [PATCH 098/156] fix: restore RNScreenStackmanager for Fabric impl --- ios/RNSScreenStack.h | 2 -- ios/RNSScreenStack.mm | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/ios/RNSScreenStack.h b/ios/RNSScreenStack.h index 86035ff41a..225d02a82e 100644 --- a/ios/RNSScreenStack.h +++ b/ios/RNSScreenStack.h @@ -30,10 +30,8 @@ NS_ASSUME_NONNULL_BEGIN @end -#ifndef RN_FABRIC_ENABLED @interface RNSScreenStackManager : RCTViewManager @end -#endif NS_ASSUME_NONNULL_END diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index e86e414bf0..f82e11fe6d 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -1053,7 +1053,6 @@ - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer return RNSScreenStackView.class; } -#ifndef RN_FABRIC_ENABLED @implementation RNSScreenStackManager { NSPointerArray *_stacks; } @@ -1062,6 +1061,7 @@ @implementation RNSScreenStackManager { RCT_EXPORT_VIEW_PROPERTY(onFinishTransitioning, RCTDirectEventBlock); +#ifndef RN_FABRIC_ENABLED - (UIView *)view { RNSScreenStackView *view = [[RNSScreenStackView alloc] initWithManager:self]; @@ -1071,6 +1071,7 @@ - (UIView *)view [_stacks addPointer:(__bridge void *)view]; return view; } +#endif // RN_FABRIC_ENABLED - (void)invalidate { @@ -1081,4 +1082,3 @@ - (void)invalidate } @end -#endif From c03b80903c098f0cf3ea0ae7b3281b84e6db2a27 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 10:36:54 +0200 Subject: [PATCH 099/156] chore: remove bridge reference & constructor suggested by @WoLewicki --- ios/RNSScreenStackHeaderSubview.h | 3 --- ios/RNSScreenStackHeaderSubview.mm | 10 +--------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/ios/RNSScreenStackHeaderSubview.h b/ios/RNSScreenStackHeaderSubview.h index 05cb22758c..79b4c37596 100644 --- a/ios/RNSScreenStackHeaderSubview.h +++ b/ios/RNSScreenStackHeaderSubview.h @@ -19,9 +19,6 @@ NS_ASSUME_NONNULL_BEGIN #endif @property (nonatomic) RNSScreenStackHeaderSubviewType type; -@property (nonatomic, weak) RCTBridge *bridge; // TODO: consider moving this to paper only section -- (instancetype)initWithBridge:(RCTBridge *)bridge; // TODO: consider moving this to paper only section - // right now it is possible to call this code in Fabric impl #ifndef RN_FABRIC_ENABLED @property (nonatomic, weak) UIView *reactSuperview; diff --git a/ios/RNSScreenStackHeaderSubview.mm b/ios/RNSScreenStackHeaderSubview.mm index 98e37abd11..d7dc30173e 100644 --- a/ios/RNSScreenStackHeaderSubview.mm +++ b/ios/RNSScreenStackHeaderSubview.mm @@ -18,14 +18,6 @@ @implementation RNSScreenStackHeaderSubview { #pragma mark - Common -- (instancetype)initWithBridge:(RCTBridge *)bridge -{ - if (self = [super init]) { - _bridge = bridge; - } - return self; -} - #ifdef RN_FABRIC_ENABLED #pragma mark - Fabric specific @@ -110,7 +102,7 @@ @implementation RNSScreenStackHeaderSubviewManager - (UIView *)view { - return [[RNSScreenStackHeaderSubview alloc] initWithBridge:self.bridge]; + return [RNSScreenStackHeaderSubview new]; } @end From 953299e3365edc9abca57a7b5c35b3323df74658 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 11:26:07 +0200 Subject: [PATCH 100/156] fix: make TestsExample compile Notice change of RNSScreenView#controller type from UIViewController to RNSScreen --- ios/RNSConvert.h | 3 ++ ios/RNSConvert.mm | 3 ++ ios/RNSScreen.h | 3 +- ios/RNSScreen.mm | 30 +++++++++---------- ios/RNSScreenStackComponentView.h | 3 ++ ios/RNSScreenStackComponentView.mm | 3 ++ ios/RNSScreenStackHeaderConfigComponentView.h | 2 ++ ...RNSScreenStackHeaderConfigComponentView.mm | 3 ++ ...RNSScreenStackHeaderSubviewComponentView.h | 3 ++ ...NSScreenStackHeaderSubviewComponentView.mm | 3 ++ 10 files changed, 38 insertions(+), 18 deletions(-) diff --git a/ios/RNSConvert.h b/ios/RNSConvert.h index 2bb24c9503..e6e8774e1f 100644 --- a/ios/RNSConvert.h +++ b/ios/RNSConvert.h @@ -1,6 +1,7 @@ #ifndef RNSConvert_h #define RNSConvert_h +#ifdef RN_FABRIC_ENABLED #import #import "RNSEnums.h" @@ -14,4 +15,6 @@ @end +#endif // RN_FABRIC_ENABLED + #endif /* RNSConvert_h */ diff --git a/ios/RNSConvert.mm b/ios/RNSConvert.mm index 8db9635408..6207db99b9 100644 --- a/ios/RNSConvert.mm +++ b/ios/RNSConvert.mm @@ -1,5 +1,6 @@ #import "RNSConvert.h" +#ifdef RN_FABRIC_ENABLED @implementation RNSConvert + (RNSScreenStackPresentation)RNSScreenStackPresentationFromCppEquivalent: @@ -48,3 +49,5 @@ + (RNSScreenStackAnimation)RNSScreenStackAnimationFromCppEquivalent: } @end + +#endif // RN_FABRIC_ENABLED diff --git a/ios/RNSScreen.h b/ios/RNSScreen.h index 265854039f..7d48f5e5ce 100644 --- a/ios/RNSScreen.h +++ b/ios/RNSScreen.h @@ -59,6 +59,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) RNSScreenReplaceAnimation replaceAnimation; @property (nonatomic, retain) NSNumber *transitionDuration; @property (nonatomic, readonly) BOOL dismissed; +@property (nonatomic, retain) RNSScreen *controller; #if !TARGET_OS_TV @property (nonatomic) RNSStatusBarStyle statusBarStyle; @@ -71,7 +72,6 @@ NS_ASSUME_NONNULL_BEGIN #ifdef RN_FABRIC_ENABLED @property (weak, nonatomic) UIView *config; @property (weak, nonatomic) UIView *reactSuperview; -@property (nonatomic, retain) RNSScreen *controller; #else @property (nonatomic, copy) RCTDirectEventBlock onAppear; @property (nonatomic, copy) RCTDirectEventBlock onDisappear; @@ -82,7 +82,6 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy) RCTDirectEventBlock onTransitionProgress; @property (weak, nonatomic) UIView *reactSuperview; -@property (nonatomic, retain) UIViewController *controller; @property (nonatomic) int activityState; @property (nonatomic) BOOL preventNativeDismiss; @property (nonatomic) BOOL customAnimationOnSwipe; diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index e64e3a8587..8a0884fff6 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -2,34 +2,28 @@ #import "RNSScreen.h" #import "RNSScreenContainer.h" -#import "RNSScreenStack.h" -#import "RNSScreenStackHeaderConfig.h" #import "RNSScreenWindowTraits.h" -#import - -// TODO: Organize imports #ifdef RN_FABRIC_ENABLED #import +#import #import #import #import #import +#import +#import "RCTFabricComponentsPlugins.h" #import "RNSConvert.h" #import "RNSScreenStackHeaderConfigComponentView.h" #else #import +#import "RNSScreenStack.h" +#import "RNSScreenStackHeaderConfig.h" #endif #import #import -#import -#import "RCTFabricComponentsPlugins.h" - -#import -#import - @interface RNSScreenView () #ifdef RN_FABRIC_ENABLED @@ -50,6 +44,7 @@ @implementation RNSScreenView { #endif } +#ifdef RN_FABRIC_ENABLED - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { @@ -60,7 +55,7 @@ - (instancetype)initWithFrame:(CGRect)frame return self; } - +#else - (instancetype)initWithBridge:(RCTBridge *)bridge { if (self = [super init]) { @@ -70,6 +65,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge return self; } +#endif // RN_FABRIC_ENABLED - (void)initCommonProps { @@ -397,14 +393,14 @@ - (RCTTouchHandler *)touchHandler return nil; } -// altough it is fabric specific code +#pragma mark - Fabric specific +#ifdef RN_FABRIC_ENABLED + + (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider { return facebook::react::concreteComponentDescriptorProvider(); } -#pragma mark - Fabric specific -#ifdef RN_FABRIC_ENABLED - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { [super mountChildComponentView:childComponentView index:index]; @@ -516,7 +512,7 @@ - (void)setActivityStateOrNil:(NSNumber *)activityStateOrNil int activityState = [activityStateOrNil intValue]; if (activityStateOrNil != nil && activityState != _activityState) { _activityState = activityState; - [_reactSuperview markChildUpdated] + [_reactSuperview markChildUpdated]; } } @@ -581,10 +577,12 @@ - (void)invalidate @end +#ifdef RN_FABRIC_ENABLED Class RNSScreenCls(void) { return RNSScreenView.class; } +#endif #pragma mark - RNSScreen diff --git a/ios/RNSScreenStackComponentView.h b/ios/RNSScreenStackComponentView.h index 03915852ce..547d3cb492 100644 --- a/ios/RNSScreenStackComponentView.h +++ b/ios/RNSScreenStackComponentView.h @@ -1,3 +1,4 @@ +#ifdef RN_FABRIC_ENABLED #import #import @@ -13,3 +14,5 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END + +#endif // RN_FABRIC_ENABLED diff --git a/ios/RNSScreenStackComponentView.mm b/ios/RNSScreenStackComponentView.mm index f6635bacf3..3865558b93 100644 --- a/ios/RNSScreenStackComponentView.mm +++ b/ios/RNSScreenStackComponentView.mm @@ -1,3 +1,4 @@ +#ifdef RN_FABRIC_ENABLED #import "RNSScreenStackComponentView.h" #import "RNSScreen.h" #import "RNSScreenStackAnimator.h" @@ -691,3 +692,5 @@ + (ComponentDescriptorProvider)componentDescriptorProvider { return RNSScreenStackComponentView.class; } + +#endif // RN_FABRIC_ENABLED diff --git a/ios/RNSScreenStackHeaderConfigComponentView.h b/ios/RNSScreenStackHeaderConfigComponentView.h index 390023adc8..5182b6eafd 100644 --- a/ios/RNSScreenStackHeaderConfigComponentView.h +++ b/ios/RNSScreenStackHeaderConfigComponentView.h @@ -1,3 +1,4 @@ +#ifdef RN_FABRIC_ENABLED #import #import @@ -40,3 +41,4 @@ withConfig:(RNSScreenStackHeaderConfigComponentView *)config; @end +#endif diff --git a/ios/RNSScreenStackHeaderConfigComponentView.mm b/ios/RNSScreenStackHeaderConfigComponentView.mm index a0c06455f2..68b3c6a6a6 100644 --- a/ios/RNSScreenStackHeaderConfigComponentView.mm +++ b/ios/RNSScreenStackHeaderConfigComponentView.mm @@ -3,6 +3,7 @@ #import "./utils/RNSUIBarButtonItem.h" +#ifdef RN_FABRIC_ENABLED #import #import @@ -666,3 +667,5 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const & { return RNSScreenStackHeaderConfigComponentView.class; } + +#endif // RN_FABRIC_ENABLED diff --git a/ios/RNSScreenStackHeaderSubviewComponentView.h b/ios/RNSScreenStackHeaderSubviewComponentView.h index eaaa920f91..c2d9eff6bb 100644 --- a/ios/RNSScreenStackHeaderSubviewComponentView.h +++ b/ios/RNSScreenStackHeaderSubviewComponentView.h @@ -1,3 +1,4 @@ +#ifdef RN_FABRIC_ENABLED #import #import @@ -12,3 +13,5 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END + +#endif // RN_FABRIC_ENABLED diff --git a/ios/RNSScreenStackHeaderSubviewComponentView.mm b/ios/RNSScreenStackHeaderSubviewComponentView.mm index bad3ecc3fd..61c54ab587 100644 --- a/ios/RNSScreenStackHeaderSubviewComponentView.mm +++ b/ios/RNSScreenStackHeaderSubviewComponentView.mm @@ -1,3 +1,4 @@ +#ifdef RN_FABRIC_ENABLED #import "RNSScreenStackHeaderSubviewComponentView.h" #import @@ -75,3 +76,5 @@ + (ComponentDescriptorProvider)componentDescriptorProvider { return RNSScreenStackHeaderSubviewComponentView.class; } + +#endif // RN_FABRIC_ENABLED From d46daff9fb85a7bc1b49f92ad3574cacc945e95a Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:00:56 +0200 Subject: [PATCH 101/156] potentially important: remove RNSScreen *_controller field from RNSScreenView implementation --- ios/RNSScreen.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 8a0884fff6..0d3cab052d 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -33,7 +33,6 @@ @interface RNSScreenView () @end @implementation RNSScreenView { - RNSScreen *_controller; __weak RCTBridge *_bridge; #ifdef RN_FABRIC_ENABLED RCTSurfaceTouchHandler *_touchHandler; From 3fa258d8940addec9f5334897fd361221f036da0 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:16:42 +0200 Subject: [PATCH 102/156] chore: move setViewToSnapshot & resetViewToScreen methods to Fabric specific section --- ios/RNSScreen.mm | 63 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 18 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 0d3cab052d..bb2ab66b49 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -18,9 +18,9 @@ #else #import #import "RNSScreenStack.h" -#import "RNSScreenStackHeaderConfig.h" #endif +#import "RNSScreenStackHeaderConfig.h" #import #import @@ -585,37 +585,45 @@ - (void)invalidate #pragma mark - RNSScreen -#ifdef RN_FABRIC_ENABLED - @implementation RNSScreen { +#ifdef RN_FABRIC_ENABLED RNSScreenView *_initialView; +#else + __weak id _previousFirstResponder; + CGRect _lastViewFrame; + UIView *_fakeView; + CADisplayLink *_animationTimer; + CGFloat _currentAlpha; + BOOL _closing; + BOOL _goingForward; + int _dismissCount; + BOOL _isSwiping; + BOOL _shouldNotify; +#endif } +#pragma mark - Common + +// done - (instancetype)initWithView:(UIView *)view { if (self = [super init]) { self.view = view; +#ifdef RN_FABRIC_ENABLED if ([view isKindOfClass:[RNSScreenView class]]) { _initialView = (RNSScreenView *)view; } else { + // TODO: fix this message RCTLogError(@"ScreenController can only be initialized with ScreenComponentView"); } +#else + _shouldNotify = YES; + _fakeView = [UIView new]; +#endif } return self; } -- (void)setViewToSnapshot:(UIView *)snapshot -{ - [self.view removeFromSuperview]; - self.view = snapshot; -} - -- (void)resetViewToScreen -{ - [self.view removeFromSuperview]; - self.view = _initialView; -} - // TODO: Find out why this is executed when screen is going out - (void)viewWillAppear:(BOOL)animated { @@ -779,9 +787,27 @@ - (BOOL)prefersHomeIndicatorAutoHidden } #endif -@end +#ifdef RN_FABRIC_ENABLED +#pragma mark - Fabric + +- (void)setViewToSnapshot:(UIView *)snapshot +{ + [self.view removeFromSuperview]; + self.view = snapshot; +} + +- (void)resetViewToScreen +{ + [self.view removeFromSuperview]; + self.view = _initialView; +} + #else +#pragma mark - Paper specific +#endif // RN_FABRIC_ENABLED + +@end @implementation RNSScreen { __weak id _previousFirstResponder; @@ -796,6 +822,7 @@ @implementation RNSScreen { BOOL _shouldNotify; } +// done 2 - (instancetype)initWithView:(UIView *)view { if (self = [super init]) { @@ -1185,8 +1212,6 @@ - (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingFor @end -#endif // RN_FABRIC_ENABLED - @implementation RNSScreenManager RCT_EXPORT_MODULE() @@ -1220,10 +1245,12 @@ @implementation RNSScreenManager RCT_EXPORT_VIEW_PROPERTY(homeIndicatorHidden, BOOL) #endif +#ifndef RN_FABRIC_ENABLED - (UIView *)view { return [[RNSScreenView alloc] initWithBridge:self.bridge]; } +#endif @end From 519687632ce260685aa82d167979309ec0c291ca Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:18:50 +0200 Subject: [PATCH 103/156] chore: merge viewWillAppear: methods --- ios/RNSScreen.mm | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index bb2ab66b49..3917e52202 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -624,12 +624,39 @@ - (instancetype)initWithView:(UIView *)view return self; } +// done // TODO: Find out why this is executed when screen is going out - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; +#ifdef RN_FABRIC_ENABLED [RNSScreenWindowTraits updateWindowTraits]; [_initialView notifyWillAppear]; +#else + if (!_isSwiping) { + [((RNSScreenView *)self.view) notifyWillAppear]; + if (self.transitionCoordinator.isInteractive) { + // we started dismissing with swipe gesture + _isSwiping = YES; + } + } else { + // this event is also triggered if we cancelled the swipe. + // The _isSwiping is still true, but we don't want to notify then + _shouldNotify = NO; + } + + [self hideHeaderIfNecessary]; + + // as per documentation of these methods + _goingForward = [self isBeingPresented] || [self isMovingToParentViewController]; + + [RNSScreenWindowTraits updateWindowTraits]; + if (_shouldNotify) { + _closing = NO; + [self notifyTransitionProgress:0.0 closing:_closing goingForward:_goingForward]; + [self setupProgressNotification]; + } +#endif } - (void)viewWillDisappear:(BOOL)animated From a7e0329e9fc33e037e32992d4889089e3b21d0bf Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:20:26 +0200 Subject: [PATCH 104/156] chore: merge viewWillDisappear methods --- ios/RNSScreen.mm | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 3917e52202..2e7711a4c4 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -659,10 +659,45 @@ - (void)viewWillAppear:(BOOL)animated #endif } +// done - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; +#ifdef RN_FABRIC_ENABLED [_initialView notifyWillDisappear]; +#else + if (!self.transitionCoordinator.isInteractive) { + // user might have long pressed ios 14 back button item, + // so he can go back more than one screen and we need to dismiss more screens in JS stack then. + // We check it by calculating the difference between the index of currently displayed screen + // and the index of the target screen, which is the view of topViewController at this point. + // If the value is lower than 1, it means we are dismissing a modal, or navigating forward, or going back with JS. + int selfIndex = [self getIndexOfView:self.view]; + int targetIndex = [self getIndexOfView:self.navigationController.topViewController.view]; + _dismissCount = selfIndex - targetIndex > 0 ? selfIndex - targetIndex : 1; + } else { + _dismissCount = 1; + } + + // same flow as in viewWillAppear + if (!_isSwiping) { + [((RNSScreenView *)self.view) notifyWillDisappear]; + if (self.transitionCoordinator.isInteractive) { + _isSwiping = YES; + } + } else { + _shouldNotify = NO; + } + + // as per documentation of these methods + _goingForward = !([self isBeingDismissed] || [self isMovingFromParentViewController]); + + if (_shouldNotify) { + _closing = YES; + [self notifyTransitionProgress:0.0 closing:_closing goingForward:_goingForward]; + [self setupProgressNotification]; + } +#endif } - (void)viewDidAppear:(BOOL)animated From 4f0ff72553a6cecad00455d67d56e6767c3f8e18 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:21:32 +0200 Subject: [PATCH 105/156] chore: merge viewDidAppear methods --- ios/RNSScreen.mm | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 2e7711a4c4..5e3e4d8bac 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -700,10 +700,23 @@ - (void)viewWillDisappear:(BOOL)animated #endif } +// done - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; +#ifdef RN_FABRIC_ENABLED [_initialView notifyAppear]; +#else + if (!_isSwiping || _shouldNotify) { + // we are going forward or dismissing without swipe + // or successfully swiped back + [((RNSScreenView *)self.view) notifyAppear]; + [self notifyTransitionProgress:1.0 closing:NO goingForward:_goingForward]; + } + + _isSwiping = NO; + _shouldNotify = YES; +#endif } - (void)viewDidDisappear:(BOOL)animated From 2bf93c582a868bc54cd71b09615fb524bf0b6439 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:22:36 +0200 Subject: [PATCH 106/156] chore: merge viewDidDisappear methods --- ios/RNSScreen.mm | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 5e3e4d8bac..b089937fe2 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -719,14 +719,40 @@ - (void)viewDidAppear:(BOOL)animated #endif } +// done - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; +#ifdef RN_FABRIC_ENABLED [_initialView notifyDisappear]; if (self.parentViewController == nil && self.presentingViewController == nil) { // screen dismissed, send event [_initialView notifyDismissedWithCount:1]; } +#else + if (self.parentViewController == nil && self.presentingViewController == nil) { + if (((RNSScreenView *)self.view).preventNativeDismiss) { + // if we want to prevent the native dismiss, we do not send dismissal event, + // but instead call `updateContainer`, which restores the JS navigation stack + [((RNSScreenView *)self.view).reactSuperview updateContainer]; + [((RNSScreenView *)self.view) notifyDismissCancelledWithDismissCount:_dismissCount]; + } else { + // screen dismissed, send event + [((RNSScreenView *)self.view) notifyDismissedWithCount:_dismissCount]; + } + } + + // same flow as in viewDidAppear + if (!_isSwiping || _shouldNotify) { + [((RNSScreenView *)self.view) notifyDisappear]; + [self notifyTransitionProgress:1.0 closing:YES goingForward:_goingForward]; + } + + _isSwiping = NO; + _shouldNotify = YES; + + [self traverseForScrollView:self.view]; +#endif } - (void)viewDidLayoutSubviews From 55e4e19069cba65f6c1e32528c81da6c7d6724a4 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:23:56 +0200 Subject: [PATCH 107/156] chore: merge viewDidLayoutSubviews methods --- ios/RNSScreen.mm | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index b089937fe2..adc4d14ae5 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -755,13 +755,30 @@ - (void)viewDidDisappear:(BOOL)animated #endif } +// done - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; +#ifdef RN_FABRIC_ENABLED BOOL isDisplayedWithinUINavController = [self.parentViewController isKindOfClass:[UINavigationController class]]; if (isDisplayedWithinUINavController) { [_initialView updateBounds]; } +#else + // The below code makes the screen view adapt dimensions provided by the system. We take these + // into account only when the view is mounted under RNScreensNavigationController in which case system + // provides additional padding to account for possible header, and in the case when screen is + // shown as a native modal, as the final dimensions of the modal on iOS 12+ are shorter than the + // screen size + BOOL isDisplayedWithinUINavController = + [self.parentViewController isKindOfClass:[RNScreensNavigationController class]]; + BOOL isPresentedAsNativeModal = self.parentViewController == nil && self.presentingViewController != nil; + if ((isDisplayedWithinUINavController || isPresentedAsNativeModal) && + !CGRectEqualToRect(_lastViewFrame, self.view.frame)) { + _lastViewFrame = self.view.frame; + [((RNSScreenView *)self.viewIfLoaded) updateBounds]; + } +#endif } #if !TARGET_OS_TV From 77fe9082564ff88fe349139756bdaca9dac38038 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:25:47 +0200 Subject: [PATCH 108/156] chore: move findFirstResponder method to paper specific section --- ios/RNSScreen.mm | 391 +---------------------------------------------- 1 file changed, 1 insertion(+), 390 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index adc4d14ae5..e030db91e2 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -923,177 +923,6 @@ - (void)resetViewToScreen #else #pragma mark - Paper specific -#endif // RN_FABRIC_ENABLED - -@end - -@implementation RNSScreen { - __weak id _previousFirstResponder; - CGRect _lastViewFrame; - UIView *_fakeView; - CADisplayLink *_animationTimer; - CGFloat _currentAlpha; - BOOL _closing; - BOOL _goingForward; - int _dismissCount; - BOOL _isSwiping; - BOOL _shouldNotify; -} - -// done 2 -- (instancetype)initWithView:(UIView *)view -{ - if (self = [super init]) { - self.view = view; - _shouldNotify = YES; - _fakeView = [UIView new]; - } - return self; -} - -#if !TARGET_OS_TV -- (UIViewController *)childViewControllerForStatusBarStyle -{ - UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitStyle includingModals:NO]; - return vc == self ? nil : vc; -} - -- (UIStatusBarStyle)preferredStatusBarStyle -{ - return [RNSScreenWindowTraits statusBarStyleForRNSStatusBarStyle:((RNSScreenView *)self.view).statusBarStyle]; -} - -- (UIViewController *)childViewControllerForStatusBarHidden -{ - UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitHidden includingModals:NO]; - return vc == self ? nil : vc; -} - -- (BOOL)prefersStatusBarHidden -{ - return ((RNSScreenView *)self.view).statusBarHidden; -} - -- (UIStatusBarAnimation)preferredStatusBarUpdateAnimation -{ - UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitAnimation includingModals:NO]; - - if ([vc isKindOfClass:[RNSScreen class]]) { - return ((RNSScreenView *)vc.view).statusBarAnimation; - } - return UIStatusBarAnimationFade; -} - -- (UIInterfaceOrientationMask)supportedInterfaceOrientations -{ - UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitOrientation includingModals:YES]; - - if ([vc isKindOfClass:[RNSScreen class]]) { - return ((RNSScreenView *)vc.view).screenOrientation; - } - return UIInterfaceOrientationMaskAllButUpsideDown; -} - -- (UIViewController *)childViewControllerForHomeIndicatorAutoHidden -{ - UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitHomeIndicatorHidden includingModals:YES]; - return vc == self ? nil : vc; -} - -- (BOOL)prefersHomeIndicatorAutoHidden -{ - return ((RNSScreenView *)self.view).homeIndicatorHidden; -} - -// if the returned vc is a child, it means that it can provide config; -// if the returned vc is self, it means that there is no child for config and self has config to provide, -// so we return self which results in asking self for preferredStatusBarStyle/Animation etc.; -// if the returned vc is nil, it means none of children could provide config and self does not have config either, -// so if it was asked by parent, it will fallback to parent's option, or use default option if it is the top Screen -- (UIViewController *)findChildVCForConfigAndTrait:(RNSWindowTrait)trait includingModals:(BOOL)includingModals -{ - UIViewController *lastViewController = [[self childViewControllers] lastObject]; - if ([self.presentedViewController isKindOfClass:[RNSScreen class]]) { - lastViewController = self.presentedViewController; - // we don't want to allow controlling of status bar appearance when we present non-fullScreen modal - // and it is not possible if `modalPresentationCapturesStatusBarAppearance` is not set to YES, so even - // if we went into a modal here and ask it, it wouldn't take any effect. For fullScreen modals, the system - // asks them by itself, so we can stop traversing here. - // for screen orientation, we need to start the search again from that modal - return !includingModals - ? nil - : [(RNSScreen *)lastViewController findChildVCForConfigAndTrait:trait includingModals:includingModals] - ?: lastViewController; - } - - UIViewController *selfOrNil = [self hasTraitSet:trait] ? self : nil; - if (lastViewController == nil) { - return selfOrNil; - } else { - if ([lastViewController conformsToProtocol:@protocol(RNScreensViewControllerDelegate)]) { - // If there is a child (should be VC of ScreenContainer or ScreenStack), that has a child that could provide the - // trait, we recursively go into its findChildVCForConfig, and if one of the children has the trait set, we return - // it, otherwise we return self if this VC has config, and nil if it doesn't we use - // `childViewControllerForStatusBarStyle` for all options since the behavior is the same for all of them - UIViewController *childScreen = [lastViewController childViewControllerForStatusBarStyle]; - if ([childScreen isKindOfClass:[RNSScreen class]]) { - return [(RNSScreen *)childScreen findChildVCForConfigAndTrait:trait includingModals:includingModals] - ?: selfOrNil; - } else { - return selfOrNil; - } - } else { - // child vc is not from this library, so we don't ask it - return selfOrNil; - } - } -} - -- (BOOL)hasTraitSet:(RNSWindowTrait)trait -{ - switch (trait) { - case RNSWindowTraitStyle: { - return ((RNSScreenView *)self.view).hasStatusBarStyleSet; - } - case RNSWindowTraitAnimation: { - return ((RNSScreenView *)self.view).hasStatusBarAnimationSet; - } - case RNSWindowTraitHidden: { - return ((RNSScreenView *)self.view).hasStatusBarHiddenSet; - } - case RNSWindowTraitOrientation: { - return ((RNSScreenView *)self.view).hasOrientationSet; - } - case RNSWindowTraitHomeIndicatorHidden: { - return ((RNSScreenView *)self.view).hasHomeIndicatorHiddenSet; - } - default: { - RCTLogError(@"Unknown trait passed: %d", (int)trait); - } - } - return NO; -} - -#endif - -- (void)viewDidLayoutSubviews -{ - [super viewDidLayoutSubviews]; - - // The below code makes the screen view adapt dimensions provided by the system. We take these - // into account only when the view is mounted under RNScreensNavigationController in which case system - // provides additional padding to account for possible header, and in the case when screen is - // shown as a native modal, as the final dimensions of the modal on iOS 12+ are shorter than the - // screen size - BOOL isDisplayedWithinUINavController = - [self.parentViewController isKindOfClass:[RNScreensNavigationController class]]; - BOOL isPresentedAsNativeModal = self.parentViewController == nil && self.presentingViewController != nil; - if ((isDisplayedWithinUINavController || isPresentedAsNativeModal) && - !CGRectEqualToRect(_lastViewFrame, self.view.frame)) { - _lastViewFrame = self.view.frame; - [((RNSScreenView *)self.viewIfLoaded) updateBounds]; - } -} - (id)findFirstResponder:(UIView *)parent { @@ -1108,225 +937,7 @@ - (id)findFirstResponder:(UIView *)parent } return nil; } - -- (void)willMoveToParentViewController:(UIViewController *)parent -{ - [super willMoveToParentViewController:parent]; - if (parent == nil) { - id responder = [self findFirstResponder:self.view]; - if (responder != nil) { - _previousFirstResponder = responder; - } - } -} - -- (void)viewWillAppear:(BOOL)animated -{ - [super viewWillAppear:animated]; - - if (!_isSwiping) { - [((RNSScreenView *)self.view) notifyWillAppear]; - if (self.transitionCoordinator.isInteractive) { - // we started dismissing with swipe gesture - _isSwiping = YES; - } - } else { - // this event is also triggered if we cancelled the swipe. - // The _isSwiping is still true, but we don't want to notify then - _shouldNotify = NO; - } - - [self hideHeaderIfNecessary]; - - // as per documentation of these methods - _goingForward = [self isBeingPresented] || [self isMovingToParentViewController]; - - [RNSScreenWindowTraits updateWindowTraits]; - if (_shouldNotify) { - _closing = NO; - [self notifyTransitionProgress:0.0 closing:_closing goingForward:_goingForward]; - [self setupProgressNotification]; - } -} - -- (void)hideHeaderIfNecessary -{ -#if !TARGET_OS_TV - // On iOS >=13, there is a bug when user transitions from screen with active search bar to screen without header - // In that case default iOS header will be shown. To fix this we hide header when the screens that appears has header - // hidden and search bar was active on previous screen. We need to do it asynchronously, because default header is - // added after viewWillAppear. - if (@available(iOS 13.0, *)) { - NSUInteger currentIndex = [self.navigationController.viewControllers indexOfObject:self]; - - if (currentIndex > 0 && [self.view.reactSubviews[0] isKindOfClass:[RNSScreenStackHeaderConfig class]]) { - UINavigationItem *prevNavigationItem = - [self.navigationController.viewControllers objectAtIndex:currentIndex - 1].navigationItem; - RNSScreenStackHeaderConfig *config = ((RNSScreenStackHeaderConfig *)self.view.reactSubviews[0]); - - BOOL wasSearchBarActive = prevNavigationItem.searchController.active; - BOOL shouldHideHeader = config.hide; - - if (wasSearchBarActive && shouldHideHeader) { - dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0); - dispatch_after(popTime, dispatch_get_main_queue(), ^(void) { - [self.navigationController setNavigationBarHidden:YES animated:NO]; - }); - } - } - } -#endif -} - -- (void)viewWillDisappear:(BOOL)animated -{ - [super viewWillDisappear:animated]; - - if (!self.transitionCoordinator.isInteractive) { - // user might have long pressed ios 14 back button item, - // so he can go back more than one screen and we need to dismiss more screens in JS stack then. - // We check it by calculating the difference between the index of currently displayed screen - // and the index of the target screen, which is the view of topViewController at this point. - // If the value is lower than 1, it means we are dismissing a modal, or navigating forward, or going back with JS. - int selfIndex = [self getIndexOfView:self.view]; - int targetIndex = [self getIndexOfView:self.navigationController.topViewController.view]; - _dismissCount = selfIndex - targetIndex > 0 ? selfIndex - targetIndex : 1; - } else { - _dismissCount = 1; - } - - // same flow as in viewWillAppear - if (!_isSwiping) { - [((RNSScreenView *)self.view) notifyWillDisappear]; - if (self.transitionCoordinator.isInteractive) { - _isSwiping = YES; - } - } else { - _shouldNotify = NO; - } - - // as per documentation of these methods - _goingForward = !([self isBeingDismissed] || [self isMovingFromParentViewController]); - - if (_shouldNotify) { - _closing = YES; - [self notifyTransitionProgress:0.0 closing:_closing goingForward:_goingForward]; - [self setupProgressNotification]; - } -} - -- (void)viewDidAppear:(BOOL)animated -{ - [super viewDidAppear:animated]; - - if (!_isSwiping || _shouldNotify) { - // we are going forward or dismissing without swipe - // or successfully swiped back - [((RNSScreenView *)self.view) notifyAppear]; - [self notifyTransitionProgress:1.0 closing:NO goingForward:_goingForward]; - } - - _isSwiping = NO; - _shouldNotify = YES; -} - -- (void)viewDidDisappear:(BOOL)animated -{ - [super viewDidDisappear:animated]; - - if (self.parentViewController == nil && self.presentingViewController == nil) { - if (((RNSScreenView *)self.view).preventNativeDismiss) { - // if we want to prevent the native dismiss, we do not send dismissal event, - // but instead call `updateContainer`, which restores the JS navigation stack - [((RNSScreenView *)self.view).reactSuperview updateContainer]; - [((RNSScreenView *)self.view) notifyDismissCancelledWithDismissCount:_dismissCount]; - } else { - // screen dismissed, send event - [((RNSScreenView *)self.view) notifyDismissedWithCount:_dismissCount]; - } - } - - // same flow as in viewDidAppear - if (!_isSwiping || _shouldNotify) { - [((RNSScreenView *)self.view) notifyDisappear]; - [self notifyTransitionProgress:1.0 closing:YES goingForward:_goingForward]; - } - - _isSwiping = NO; - _shouldNotify = YES; - - [self traverseForScrollView:self.view]; -} - -- (void)traverseForScrollView:(UIView *)view -{ - if (![[self.view valueForKey:@"_bridge"] valueForKey:@"_jsThread"]) { - // we don't want to send `scrollViewDidEndDecelerating` event to JS before the JS thread is ready - return; - } - if ([view isKindOfClass:[UIScrollView class]] && - ([[(UIScrollView *)view delegate] respondsToSelector:@selector(scrollViewDidEndDecelerating:)])) { - [[(UIScrollView *)view delegate] scrollViewDidEndDecelerating:(id)view]; - } - [view.subviews enumerateObjectsUsingBlock:^(__kindof UIView *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { - [self traverseForScrollView:obj]; - }]; -} - -- (int)getIndexOfView:(UIView *)view -{ - return (int)[[self.view.reactSuperview reactSubviews] indexOfObject:view]; -} - -- (int)getParentChildrenCount -{ - return (int)[[self.view.reactSuperview reactSubviews] count]; -} - -- (void)notifyFinishTransitioning -{ - [_previousFirstResponder becomeFirstResponder]; - _previousFirstResponder = nil; - // the correct Screen for appearance is set after the transition, same for orientation. - [RNSScreenWindowTraits updateWindowTraits]; -} - -#pragma mark - transition progress related methods - -- (void)setupProgressNotification -{ - if (self.transitionCoordinator != nil) { - _fakeView.alpha = 0.0; - [self.transitionCoordinator - animateAlongsideTransition:^(id _Nonnull context) { - [[context containerView] addSubview:self->_fakeView]; - self->_fakeView.alpha = 1.0; - self->_animationTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleAnimation)]; - [self->_animationTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; - } - completion:^(id _Nonnull context) { - [self->_animationTimer setPaused:YES]; - [self->_animationTimer invalidate]; - [self->_fakeView removeFromSuperview]; - }]; - } -} - -- (void)handleAnimation -{ - if ([[_fakeView layer] presentationLayer] != nil) { - CGFloat fakeViewAlpha = _fakeView.layer.presentationLayer.opacity; - if (_currentAlpha != fakeViewAlpha) { - _currentAlpha = fmax(0.0, fmin(1.0, fakeViewAlpha)); - [self notifyTransitionProgress:_currentAlpha closing:_closing goingForward:_goingForward]; - } - } -} - -- (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingForward:(BOOL)goingForward -{ - [((RNSScreenView *)self.view) notifyTransitionProgress:progress closing:closing goingForward:goingForward]; -} +#endif // RN_FABRIC_ENABLED @end From 51938213ced0af40fbae413fa8afccd340ac8a1f Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:31:38 +0200 Subject: [PATCH 109/156] chore: move willMoveToParentViewController method to paper specific section --- ios/RNSScreen.mm | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index e030db91e2..7498ff3d69 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -787,6 +787,7 @@ - (void)viewDidLayoutSubviews // so we return self which results in asking self for preferredStatusBarStyle/Animation etc.; // if the returned vc is nil, it means none of children could provide config and self does not have config either, // so if it was asked by parent, it will fallback to parent's option, or use default option if it is the top Screen +// done - (UIViewController *)findChildVCForConfigAndTrait:(RNSWindowTrait)trait includingModals:(BOOL)includingModals { UIViewController *lastViewController = [[self childViewControllers] lastObject]; @@ -826,6 +827,7 @@ - (UIViewController *)findChildVCForConfigAndTrait:(RNSWindowTrait)trait includi } } +// done - (BOOL)hasTraitSet:(RNSWindowTrait)trait { switch (trait) { @@ -906,7 +908,7 @@ - (BOOL)prefersHomeIndicatorAutoHidden #endif #ifdef RN_FABRIC_ENABLED -#pragma mark - Fabric +#pragma mark - Fabric specific - (void)setViewToSnapshot:(UIView *)snapshot { @@ -937,6 +939,17 @@ - (id)findFirstResponder:(UIView *)parent } return nil; } + +- (void)willMoveToParentViewController:(UIViewController *)parent +{ + [super willMoveToParentViewController:parent]; + if (parent == nil) { + id responder = [self findFirstResponder:self.view]; + if (responder != nil) { + _previousFirstResponder = responder; + } + } +} #endif // RN_FABRIC_ENABLED @end From 834ade9687e7e74c8cc4d4a459b792932e2c89d4 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:33:46 +0200 Subject: [PATCH 110/156] chore: move hideHeaderIfNecessary method to paper specific section --- ios/RNSScreen.mm | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 7498ff3d69..f2eb220205 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -950,6 +950,35 @@ - (void)willMoveToParentViewController:(UIViewController *)parent } } } + +- (void)hideHeaderIfNecessary +{ +#if !TARGET_OS_TV + // On iOS >=13, there is a bug when user transitions from screen with active search bar to screen without header + // In that case default iOS header will be shown. To fix this we hide header when the screens that appears has header + // hidden and search bar was active on previous screen. We need to do it asynchronously, because default header is + // added after viewWillAppear. + if (@available(iOS 13.0, *)) { + NSUInteger currentIndex = [self.navigationController.viewControllers indexOfObject:self]; + + if (currentIndex > 0 && [self.view.reactSubviews[0] isKindOfClass:[RNSScreenStackHeaderConfig class]]) { + UINavigationItem *prevNavigationItem = + [self.navigationController.viewControllers objectAtIndex:currentIndex - 1].navigationItem; + RNSScreenStackHeaderConfig *config = ((RNSScreenStackHeaderConfig *)self.view.reactSubviews[0]); + + BOOL wasSearchBarActive = prevNavigationItem.searchController.active; + BOOL shouldHideHeader = config.hide; + + if (wasSearchBarActive && shouldHideHeader) { + dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0); + dispatch_after(popTime, dispatch_get_main_queue(), ^(void) { + [self.navigationController setNavigationBarHidden:YES animated:NO]; + }); + } + } + } +#endif +} #endif // RN_FABRIC_ENABLED @end From 53fd0099516c4566a2bbde27001733718ca55d73 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:43:47 +0200 Subject: [PATCH 111/156] chore: move traverseForScrollView: method to paper specific section --- ios/RNSScreen.mm | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index f2eb220205..50e0036e16 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -979,6 +979,22 @@ - (void)hideHeaderIfNecessary } #endif } + +- (void)traverseForScrollView:(UIView *)view +{ + if (![[self.view valueForKey:@"_bridge"] valueForKey:@"_jsThread"]) { + // we don't want to send `scrollViewDidEndDecelerating` event to JS before the JS thread is ready + return; + } + if ([view isKindOfClass:[UIScrollView class]] && + ([[(UIScrollView *)view delegate] respondsToSelector:@selector(scrollViewDidEndDecelerating:)])) { + [[(UIScrollView *)view delegate] scrollViewDidEndDecelerating:(id)view]; + } + [view.subviews enumerateObjectsUsingBlock:^(__kindof UIView *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { + [self traverseForScrollView:obj]; + }]; +} + #endif // RN_FABRIC_ENABLED @end From b946e61078a0e27b1b0dbd1a2c011f80a23c66be Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:46:48 +0200 Subject: [PATCH 112/156] chore: move methods connected to transitioning to paper specific section temporary solution until it is not migrated --- ios/RNSScreen.mm | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 50e0036e16..65926cff7c 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -995,6 +995,52 @@ - (void)traverseForScrollView:(UIView *)view }]; } +- (int)getIndexOfView:(UIView *)view +{ + return (int)[[self.view.reactSuperview reactSubviews] indexOfObject:view]; +} + +- (int)getParentChildrenCount +{ + return (int)[[self.view.reactSuperview reactSubviews] count]; +} + +#pragma mark - transition progress related methods + +- (void)setupProgressNotification +{ + if (self.transitionCoordinator != nil) { + _fakeView.alpha = 0.0; + [self.transitionCoordinator + animateAlongsideTransition:^(id _Nonnull context) { + [[context containerView] addSubview:self->_fakeView]; + self->_fakeView.alpha = 1.0; + self->_animationTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleAnimation)]; + [self->_animationTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + } + completion:^(id _Nonnull context) { + [self->_animationTimer setPaused:YES]; + [self->_animationTimer invalidate]; + [self->_fakeView removeFromSuperview]; + }]; + } +} + +- (void)handleAnimation +{ + if ([[_fakeView layer] presentationLayer] != nil) { + CGFloat fakeViewAlpha = _fakeView.layer.presentationLayer.opacity; + if (_currentAlpha != fakeViewAlpha) { + _currentAlpha = fmax(0.0, fmin(1.0, fakeViewAlpha)); + [self notifyTransitionProgress:_currentAlpha closing:_closing goingForward:_goingForward]; + } + } +} + +- (void)notifyTransitionProgress:(double)progress closing:(BOOL)closing goingForward:(BOOL)goingForward +{ + [((RNSScreenView *)self.view) notifyTransitionProgress:progress closing:closing goingForward:goingForward]; +} #endif // RN_FABRIC_ENABLED @end From c2925e3ce099d1e1e2aabd7e1ffa8d4cbe9fae33 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 12:57:41 +0200 Subject: [PATCH 113/156] refact: apply linter suggestions --- ios/RNSScreen.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 65926cff7c..a5e926e6fd 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -20,9 +20,9 @@ #import "RNSScreenStack.h" #endif -#import "RNSScreenStackHeaderConfig.h" #import #import +#import "RNSScreenStackHeaderConfig.h" @interface RNSScreenView () #ifdef RN_FABRIC_ENABLED @@ -922,7 +922,6 @@ - (void)resetViewToScreen self.view = _initialView; } - #else #pragma mark - Paper specific From 44368ed4f7431834a24f6ba8766b56fdace62c64 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 13:05:57 +0200 Subject: [PATCH 114/156] chore: remove leftover comments --- ios/RNSScreen.mm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 65926cff7c..8408ebf2cb 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -604,7 +604,6 @@ @implementation RNSScreen { #pragma mark - Common -// done - (instancetype)initWithView:(UIView *)view { if (self = [super init]) { @@ -624,7 +623,6 @@ - (instancetype)initWithView:(UIView *)view return self; } -// done // TODO: Find out why this is executed when screen is going out - (void)viewWillAppear:(BOOL)animated { @@ -659,7 +657,6 @@ - (void)viewWillAppear:(BOOL)animated #endif } -// done - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; @@ -700,7 +697,6 @@ - (void)viewWillDisappear:(BOOL)animated #endif } -// done - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; @@ -719,7 +715,6 @@ - (void)viewDidAppear:(BOOL)animated #endif } -// done - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; @@ -755,7 +750,6 @@ - (void)viewDidDisappear:(BOOL)animated #endif } -// done - (void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; @@ -787,7 +781,6 @@ - (void)viewDidLayoutSubviews // so we return self which results in asking self for preferredStatusBarStyle/Animation etc.; // if the returned vc is nil, it means none of children could provide config and self does not have config either, // so if it was asked by parent, it will fallback to parent's option, or use default option if it is the top Screen -// done - (UIViewController *)findChildVCForConfigAndTrait:(RNSWindowTrait)trait includingModals:(BOOL)includingModals { UIViewController *lastViewController = [[self childViewControllers] lastObject]; @@ -827,7 +820,6 @@ - (UIViewController *)findChildVCForConfigAndTrait:(RNSWindowTrait)trait includi } } -// done - (BOOL)hasTraitSet:(RNSWindowTrait)trait { switch (trait) { From 0ab05f33de5be9870e937244bbe48d06015eb672 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 13:22:04 +0200 Subject: [PATCH 115/156] refact: rename BASE_VIEW -> RNS_BASE_VIEW --- ios/RNSScreen.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ios/RNSScreen.h b/ios/RNSScreen.h index 7d48f5e5ce..f04b1393b4 100644 --- a/ios/RNSScreen.h +++ b/ios/RNSScreen.h @@ -39,12 +39,12 @@ NS_ASSUME_NONNULL_BEGIN @end #ifdef RN_FABRIC_ENABLED -#define BASE_VIEW RCTViewComponentView +#define RNS_BASE_VIEW RCTViewComponentView #else -#define BASE_VIEW RCTView +#define RNS_BASE_VIEW RCTView #endif -@interface RNSScreenView : BASE_VIEW +@interface RNSScreenView : RNS_BASE_VIEW @property (nonatomic) BOOL fullScreenSwipeEnabled; @property (nonatomic) BOOL gestureEnabled; From 15a30cfca7b234b88f60b61d312457acae190249 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 13:23:16 +0200 Subject: [PATCH 116/156] refact: apply linter suggestions --- ios/RNSScreen.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 8408ebf2cb..4a9e24c529 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -20,9 +20,9 @@ #import "RNSScreenStack.h" #endif -#import "RNSScreenStackHeaderConfig.h" #import #import +#import "RNSScreenStackHeaderConfig.h" @interface RNSScreenView () #ifdef RN_FABRIC_ENABLED @@ -914,7 +914,6 @@ - (void)resetViewToScreen self.view = _initialView; } - #else #pragma mark - Paper specific From 0afaafd97f87793d6b84b5ed280250d047b99eec Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Apr 2022 13:24:11 +0200 Subject: [PATCH 117/156] =?UTF-8?q?refact:=20rename=20EXPECTED=5FVIEW=20->?= =?UTF-8?q?=20RNS=5FEXPECTED=5FVIEW=C2=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/RNSScreen.mm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index 4a9e24c529..b7d4f2d85e 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -342,17 +342,17 @@ - (void)notifyDisappear - (BOOL)isMountedUnderScreenOrReactRoot { #ifdef RN_FABRIC_ENABLED -#define EXPECTED_VIEW RCTRootComponentView +#define RNS_EXPECTED_VIEW RCTRootComponentView #else -#define EXPECTED_VIEW RCTRootView +#define RNS_EXPECTED_VIEW RCTRootView #endif for (UIView *parent = self.superview; parent != nil; parent = parent.superview) { - if ([parent isKindOfClass:[EXPECTED_VIEW class]] || [parent isKindOfClass:[RNSScreenView class]]) { + if ([parent isKindOfClass:[RNS_EXPECTED_VIEW class]] || [parent isKindOfClass:[RNSScreenView class]]) { return YES; } } return NO; -#undef EXPECTED_VIEW +#undef RNS_EXPECTED_VIEW } - (void)didMoveToWindow From d0f128d3e782421e8151630580dadb873cda2c8a Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 22 Apr 2022 09:22:21 +0200 Subject: [PATCH 118/156] chore: restore back initWithBridge method for Fabric Fabric implementation does not need it, but RNSScreenManager is required --- ios/RNSScreen.mm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index b7d4f2d85e..f2868d39e7 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -54,7 +54,8 @@ - (instancetype)initWithFrame:(CGRect)frame return self; } -#else +#endif + - (instancetype)initWithBridge:(RCTBridge *)bridge { if (self = [super init]) { @@ -64,7 +65,6 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge return self; } -#endif // RN_FABRIC_ENABLED - (void)initCommonProps { @@ -1069,12 +1069,10 @@ @implementation RNSScreenManager RCT_EXPORT_VIEW_PROPERTY(homeIndicatorHidden, BOOL) #endif -#ifndef RN_FABRIC_ENABLED - (UIView *)view { return [[RNSScreenView alloc] initWithBridge:self.bridge]; } -#endif @end From d6ccca123c56d7ddca2ab2709bdce70469da990c Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 22 Apr 2022 09:23:16 +0200 Subject: [PATCH 119/156] fix: restore back notifyFinishTransitioning method for paper --- ios/RNSScreen.mm | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index f2868d39e7..7c68a459eb 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -998,6 +998,14 @@ - (int)getParentChildrenCount #pragma mark - transition progress related methods +- (void)notifyFinishTransitioning +{ + [_previousFirstResponder becomeFirstResponder]; + _previousFirstResponder = nil; + // the correct Screen for appearance is set after the transition, same for orientation. + [RNSScreenWindowTraits updateWindowTraits]; +} + - (void)setupProgressNotification { if (self.transitionCoordinator != nil) { From d465135a5ddce2d65f8c89c0cfbb0a7778723efe Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 22 Apr 2022 11:00:06 +0200 Subject: [PATCH 120/156] fix: tvOS: exclude props not existion on tv platform --- ios/RNSScreen.mm | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index dfa9b410c1..b2e5783057 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -441,6 +441,7 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props [self setTransitionDuration:[NSNumber numberWithInt:newScreenProps.transitionDuration]]; +#if !TARGET_OS_TV if (newScreenProps.statusBarHidden != oldScreenProps.statusBarHidden) { [self setStatusBarHidden:newScreenProps.statusBarHidden]; } @@ -459,6 +460,7 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props [self setScreenOrientation:[RCTConvert UIInterfaceOrientationMask:RCTNSStringFromStringNilIfEmpty( newScreenProps.screenOrientation)]]; } +#endif if (newScreenProps.stackPresentation != oldScreenProps.stackPresentation) { [self @@ -1089,16 +1091,6 @@ - (UIView *)view @implementation RCTConvert (RNSScreen) -RCT_ENUM_CONVERTER( - UIStatusBarAnimation, - (@{ - @"none" : @(UIStatusBarAnimationNone), - @"fade" : @(UIStatusBarAnimationFade), - @"slide" : @(UIStatusBarAnimationSlide) - }), - UIStatusBarAnimationNone, - integerValue) - RCT_ENUM_CONVERTER( RNSScreenStackPresentation, (@{ @@ -1148,6 +1140,16 @@ @implementation RCTConvert (RNSScreen) integerValue) #if !TARGET_OS_TV +RCT_ENUM_CONVERTER( + UIStatusBarAnimation, + (@{ + @"none" : @(UIStatusBarAnimationNone), + @"fade" : @(UIStatusBarAnimationFade), + @"slide" : @(UIStatusBarAnimationSlide) + }), + UIStatusBarAnimationNone, + integerValue) + RCT_ENUM_CONVERTER( RNSStatusBarStyle, (@{ From f0e42f0ca288005230153ed00f0b88ad536f2cb7 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 22 Apr 2022 11:05:55 +0200 Subject: [PATCH 121/156] chore: remove unnecessary header guard directives from RNSConvert.h --- ios/RNSConvert.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ios/RNSConvert.h b/ios/RNSConvert.h index e6e8774e1f..1cf1bea0d0 100644 --- a/ios/RNSConvert.h +++ b/ios/RNSConvert.h @@ -1,6 +1,3 @@ -#ifndef RNSConvert_h -#define RNSConvert_h - #ifdef RN_FABRIC_ENABLED #import #import "RNSEnums.h" @@ -16,5 +13,3 @@ @end #endif // RN_FABRIC_ENABLED - -#endif /* RNSConvert_h */ From d9bb8a64e303c8ddfd468f1577d6c3bcbf025c71 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Fri, 22 Apr 2022 11:52:44 +0200 Subject: [PATCH 122/156] chore: remove check if passed view is of class RNSScreenView see: https://github.com/software-mansion/react-native-screens/pull/1415#discussion_r855929914 --- ios/RNSScreen.mm | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ios/RNSScreen.mm b/ios/RNSScreen.mm index b2e5783057..5157abaaf4 100644 --- a/ios/RNSScreen.mm +++ b/ios/RNSScreen.mm @@ -613,12 +613,7 @@ - (instancetype)initWithView:(UIView *)view if (self = [super init]) { self.view = view; #ifdef RN_FABRIC_ENABLED - if ([view isKindOfClass:[RNSScreenView class]]) { - _initialView = (RNSScreenView *)view; - } else { - // TODO: fix this message - RCTLogError(@"ScreenController can only be initialized with ScreenComponentView"); - } + _initialView = (RNSScreenView *)view; #else _shouldNotify = YES; _fakeView = [UIView new]; From d2e57714bd69e02336a40dc4a82ff0e0f5b5565a Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 27 Apr 2022 14:00:17 +0200 Subject: [PATCH 123/156] refact: apply linter suggestion --- ios/RNSScreenStack.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 8469673529..4c7f089c61 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -480,8 +480,7 @@ - (void)setPushViewControllers:(NSArray *)controllers // if the previous top screen does not exist anymore and the new top was not on the stack before, probably replace // was called, so we check the animation if (![_controller.viewControllers containsObject:top] && - ((RNSScreenView *)top.view).replaceAnimation == RNSScreenReplaceAnimationPush) - { + ((RNSScreenView *)top.view).replaceAnimation == RNSScreenReplaceAnimationPush) { // setting new controllers with animation does `push` animation by default #ifdef RN_FABRIC_ENABLED auto screenController = (RNSScreen *)top; From 72a766b56b8b9205a4b14bc93cbc26440852f7e6 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 27 Apr 2022 14:04:26 +0200 Subject: [PATCH 124/156] fix: remove merge artifacts --- ios/RNSScreenStack.mm | 6 ------ 1 file changed, 6 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 4c7f089c61..08bb403abb 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -125,7 +125,6 @@ - (instancetype)initWithManager:(RNSScreenStackManager *)manager } return self; } -#endif // RN_FABRIC_ENABLED - (void)initCommonProps { @@ -207,10 +206,6 @@ - (void)presentationControllerDidDismiss:(UIPresentationController *)presentatio - (void)didMoveToWindow { [super didMoveToWindow]; -#ifdef RN_FABRIC_ENABLED - // for handling nested stacks - [self maybeAddToParentAndUpdateContainer]; -#else #ifdef RN_FABRIC_ENABLED // for handling nested stacks [self maybeAddToParentAndUpdateContainer]; @@ -517,7 +512,6 @@ - (void)setPushViewControllers:(NSArray *)controllers // change wasn't on the top of the stack. We don't need animation. [_controller setViewControllers:controllers animated:NO]; } -#endif } // done From 838dbc851094aacef73e3478d7eeb837dae34153 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 27 Apr 2022 14:20:33 +0200 Subject: [PATCH 125/156] fix: restore RNSScreenStackHeaderSubviewManager for Fabric implementation --- ios/RNSScreenStackHeaderConfig.h | 2 -- ios/RNSScreenStackHeaderConfig.mm | 2 -- 2 files changed, 4 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h index a1f5b109ed..1b22c005f9 100644 --- a/ios/RNSScreenStackHeaderConfig.h +++ b/ios/RNSScreenStackHeaderConfig.h @@ -80,10 +80,8 @@ typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) { @end -#ifndef RN_FABRIC_ENABLED @interface RNSScreenStackHeaderSubviewManager : RCTViewManager @property (nonatomic) RNSScreenStackHeaderSubviewType type; @end -#endif diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 874ae17231..2420932044 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -1027,7 +1027,6 @@ + (NSMutableDictionary *)blurEffectsForIOSVersion @end -#ifndef RN_FABRIC_ENABLED @implementation RNSScreenStackHeaderSubviewManager RCT_EXPORT_MODULE() @@ -1040,4 +1039,3 @@ - (UIView *)view } @end -#endif // RN_FABRIC_ENABLED From 56679d3725de6a8504be87b7def0528b9e440644 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 27 Apr 2022 14:38:04 +0200 Subject: [PATCH 126/156] fix: surround RNSScreenStackHeaderConfigCls with guard directive This is required as RCTComponentViewProtocol is not visible on paper --- ios/RNSScreenStackHeaderConfig.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 2420932044..7f9a90bec3 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -916,10 +916,12 @@ - (void)didUpdateReactSubviews #endif @end +#ifdef RN_FABRIC_ENABLED Class RNSScreenStackHeaderConfigCls(void) { return RNSScreenStackHeaderConfig.class; } +#endif @implementation RNSScreenStackHeaderConfigManager From 21314afb870d0ce621a34b6f6eba67ba22dabd93 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 27 Apr 2022 15:25:07 +0200 Subject: [PATCH 127/156] refact: copy comment from didSetProps method to layoutNavigationControllerView --- ios/RNSScreenStackHeaderConfig.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 7f9a90bec3..3bb0ee750d 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -180,6 +180,9 @@ - (void)updateViewControllerIfNeeded // done - (void)layoutNavigationControllerView { + // We need to layout navigation controller view after translucent prop changes, because otherwise + // frame of RNSScreen will not be changed and screen content will remain the same size. + // For more details look at https://github.com/software-mansion/react-native-screens/issues/1158 UIViewController *vc = _screenView.controller; UINavigationController *navctr = vc.navigationController; [navctr.view setNeedsLayout]; From 55a4d95c2b5d415a0d7678473db8d21fff3238df Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 27 Apr 2022 15:26:07 +0200 Subject: [PATCH 128/156] refact: remove leftover comments --- ios/RNSScreenStackHeaderConfig.mm | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 3bb0ee750d..7d06c4c99e 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -100,20 +100,17 @@ - (instancetype)init } #endif -// done - (UIView *)reactSuperview { return _screenView; } -// done - (void)removeFromSuperview { [super removeFromSuperview]; _screenView = nil; } -// done // this method is never invoked by the system since this view // is not added to native view hierarchy so we can apply our logic - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event @@ -153,7 +150,6 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event return nil; } -// done - (void)updateViewControllerIfNeeded { UIViewController *vc = _screenView.controller; @@ -177,7 +173,6 @@ - (void)updateViewControllerIfNeeded } } -// done - (void)layoutNavigationControllerView { // We need to layout navigation controller view after translucent prop changes, because otherwise @@ -188,7 +183,6 @@ - (void)layoutNavigationControllerView [navctr.view setNeedsLayout]; } -// done + (void)setAnimatedConfig:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config { UINavigationBar *navbar = ((UINavigationController *)vc.parentViewController).navigationBar; @@ -284,7 +278,6 @@ + (void)setAnimatedConfig:(UIViewController *)vc withConfig:(RNSScreenStackHeade } } -// done + (void)setTitleAttibutes:(NSDictionary *)attrs forButton:(UIBarButtonItem *)button { [button setTitleTextAttributes:attrs forState:UIControlStateNormal]; @@ -294,7 +287,6 @@ + (void)setTitleAttibutes:(NSDictionary *)attrs forButton:(UIBarButtonItem *)but [button setTitleTextAttributes:attrs forState:UIControlStateFocused]; } -// done + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config { #ifdef RN_FABRIC_ENABLED @@ -370,7 +362,6 @@ + (UIImage *)loadBackButtonImageInViewController:(UIViewController *)vc withConf return nil; } -// done + (void)willShowViewController:(UIViewController *)vc animated:(BOOL)animated withConfig:(RNSScreenStackHeaderConfig *)config @@ -378,7 +369,6 @@ + (void)willShowViewController:(UIViewController *)vc [self updateViewController:vc withConfig:config animated:animated]; } -// done #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \ __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc @@ -473,7 +463,6 @@ + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc } #endif -// done + (void)updateViewController:(UIViewController *)vc withConfig:(RNSScreenStackHeaderConfig *)config animated:(BOOL)animated From 84b6a01b9a793cdadca5752ea06ec553f27781c2 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 27 Apr 2022 15:44:42 +0200 Subject: [PATCH 129/156] chore: replace cust getFontFamliyPropValue method with one provided by RCTConversions --- ios/RNSScreenStackHeaderConfig.mm | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 7d06c4c99e..c773e21fcd 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -764,15 +764,6 @@ - (void)prepareForRecycle facebook::react::RNSScreenStackHeaderConfigComponentDescriptor>(); } -- (NSString *)getFontFamilyPropValue:(std::string)propValue -{ - if (propValue.length() > 0) { - return [[NSString alloc] initWithUTF8String:propValue.c_str()]; - } else { - return nil; - } -} - - (NSString *)stringToPropValue:(std::string)value { if (value.empty()) @@ -820,7 +811,7 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props _title = [self stringToPropValue:newScreenProps.title]; if (newScreenProps.titleFontFamily != oldScreenProps.titleFontFamily) { - _titleFontFamily = [self getFontFamilyPropValue:newScreenProps.titleFontFamily]; + _titleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.titleFontFamily); } _titleFontWeight = [self stringToPropValue:newScreenProps.titleFontWeight]; _titleFontSize = [self getFontSizePropValue:newScreenProps.titleFontSize]; @@ -828,7 +819,7 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props _largeTitle = newScreenProps.largeTitle; if (newScreenProps.largeTitleFontFamily != oldScreenProps.largeTitleFontFamily) { - _largeTitleFontFamily = [self getFontFamilyPropValue:newScreenProps.largeTitleFontFamily]; + _largeTitleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.largeTitleFontFamily); } _largeTitleFontWeight = [self stringToPropValue:newScreenProps.largeTitleFontWeight]; _largeTitleFontSize = [self getFontSizePropValue:newScreenProps.largeTitleFontSize]; @@ -837,7 +828,7 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props _backTitle = [self stringToPropValue:newScreenProps.backTitle]; ; if (newScreenProps.backTitleFontFamily != oldScreenProps.backTitleFontFamily) { - _backTitleFontFamily = [self getFontFamilyPropValue:newScreenProps.backTitleFontFamily]; + _backTitleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.backTitleFontFamily); } _backTitleFontSize = [self getFontSizePropValue:newScreenProps.backTitleFontSize]; _hideBackButton = newScreenProps.hideBackButton; From 3f19111b15ed4e0f9fc545bbcccf84cc9b54023e Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 27 Apr 2022 15:47:49 +0200 Subject: [PATCH 130/156] chore: replace custom stringToPropValue method with one provided by RCTConversions --- ios/RNSScreenStackHeaderConfig.mm | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index c773e21fcd..de4e45ca29 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -764,13 +764,6 @@ - (void)prepareForRecycle facebook::react::RNSScreenStackHeaderConfigComponentDescriptor>(); } -- (NSString *)stringToPropValue:(std::string)value -{ - if (value.empty()) - return nil; - return [[NSString alloc] initWithUTF8String:value.c_str()]; -} - - (NSNumber *)getFontSizePropValue:(int)value { if (value > 0) @@ -809,11 +802,11 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props needsNavigationControllerLayout = YES; } - _title = [self stringToPropValue:newScreenProps.title]; + _title = RCTNSStringFromStringNilIfEmpty(newScreenProps.title); if (newScreenProps.titleFontFamily != oldScreenProps.titleFontFamily) { _titleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.titleFontFamily); } - _titleFontWeight = [self stringToPropValue:newScreenProps.titleFontWeight]; + _titleFontWeight = RCTNSStringFromStringNilIfEmpty(newScreenProps.titleFontWeight); _titleFontSize = [self getFontSizePropValue:newScreenProps.titleFontSize]; _hideShadow = newScreenProps.hideShadow; @@ -821,12 +814,11 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props if (newScreenProps.largeTitleFontFamily != oldScreenProps.largeTitleFontFamily) { _largeTitleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.largeTitleFontFamily); } - _largeTitleFontWeight = [self stringToPropValue:newScreenProps.largeTitleFontWeight]; + _largeTitleFontWeight = RCTNSStringFromStringNilIfEmpty(newScreenProps.largeTitleFontWeight); _largeTitleFontSize = [self getFontSizePropValue:newScreenProps.largeTitleFontSize]; _largeTitleHideShadow = newScreenProps.largeTitleHideShadow; - _backTitle = [self stringToPropValue:newScreenProps.backTitle]; - ; + _backTitle = RCTNSStringFromStringNilIfEmpty(newScreenProps.backTitle); if (newScreenProps.backTitleFontFamily != oldScreenProps.backTitleFontFamily) { _backTitleFontFamily = RCTNSStringFromStringNilIfEmpty(newScreenProps.backTitleFontFamily); } From 5128931f628fd4ce3d49e616f1617960c10dbde7 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 27 Apr 2022 17:24:29 +0200 Subject: [PATCH 131/156] refact: move reactSubviews method to common section --- ios/RNSScreenStackHeaderConfig.mm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index de4e45ca29..c4c68ca6d8 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -105,6 +105,11 @@ - (UIView *)reactSuperview return _screenView; } +- (NSArray *)reactSubviews +{ + return _reactSubviews; +} + - (void)removeFromSuperview { [super removeFromSuperview]; @@ -865,11 +870,6 @@ - (void)removeReactSubview:(RNSScreenStackHeaderSubview *)subview [_reactSubviews removeObject:subview]; } -- (NSArray *)reactSubviews -{ - return _reactSubviews; -} - - (void)didSetProps:(NSArray *)changedProps { [super didSetProps:changedProps]; From fd57615b382052f5b82b1cf2813509a95268076b Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Wed, 27 Apr 2022 17:39:49 +0200 Subject: [PATCH 132/156] chore: settle down to single convention of specifing superclasses --- ios/RNSScreen.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ios/RNSScreen.h b/ios/RNSScreen.h index c8ced38992..5cbe4c0f6f 100644 --- a/ios/RNSScreen.h +++ b/ios/RNSScreen.h @@ -38,14 +38,13 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface RNSScreenView : #ifdef RN_FABRIC_ENABLED -#define RNS_BASE_VIEW RCTViewComponentView + RCTViewComponentView #else -#define RNS_BASE_VIEW RCTView + RCTView #endif -@interface RNSScreenView : RNS_BASE_VIEW - @property (nonatomic) BOOL fullScreenSwipeEnabled; @property (nonatomic) BOOL gestureEnabled; @property (nonatomic) BOOL hasStatusBarHiddenSet; From 0497dd7ed520851bf57a7222a10f466d79043278 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 08:35:01 +0200 Subject: [PATCH 133/156] refact: remove leftover TODO comment --- ios/RNSScreenStackHeaderConfig.h | 1 - 1 file changed, 1 deletion(-) diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h index df3fae10bf..c4f89b0a3c 100644 --- a/ios/RNSScreenStackHeaderConfig.h +++ b/ios/RNSScreenStackHeaderConfig.h @@ -21,7 +21,6 @@ @property (nonatomic, weak) RNSScreenView *screenView; #ifdef RN_FABRIC_ENABLED -// TODO: change type when StackHeaderSubview is merged (??) @property (nonatomic) NSMutableArray *reactSubviews; @property (nonatomic) BOOL show; #else From 7cd80e90050c029a900bbcb8e9651218e33b6f8f Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 08:37:55 +0200 Subject: [PATCH 134/156] chore: move reactSubviews prop to common section in header file also remove redeclaration in implementation --- ios/RNSScreenStackHeaderConfig.h | 2 +- ios/RNSScreenStackHeaderConfig.mm | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h index c4f89b0a3c..2d4089e7d7 100644 --- a/ios/RNSScreenStackHeaderConfig.h +++ b/ios/RNSScreenStackHeaderConfig.h @@ -19,9 +19,9 @@ #endif @property (nonatomic, weak) RNSScreenView *screenView; +@property (nonatomic) NSMutableArray *reactSubviews; #ifdef RN_FABRIC_ENABLED -@property (nonatomic) NSMutableArray *reactSubviews; @property (nonatomic) BOOL show; #else @property (nonatomic) UIBlurEffectStyle blurEffect; diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 5ea9ec6b21..ce54e12b06 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -36,7 +36,6 @@ @interface RCTImageLoader (Private) #endif @implementation RNSScreenStackHeaderConfig { - NSMutableArray *_reactSubviews; #ifdef RN_FABRIC_ENABLED BOOL _initialPropsSet; facebook::react::SharedColor _backgroundSharedColor; From 1dff42612511cf1b1db5ed19839222932e446759 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 08:42:34 +0200 Subject: [PATCH 135/156] chore: remove redundant header directives in RNSEnums.h header --- ios/RNSEnums.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ios/RNSEnums.h b/ios/RNSEnums.h index 62288753bf..84158c6004 100644 --- a/ios/RNSEnums.h +++ b/ios/RNSEnums.h @@ -1,6 +1,3 @@ -#ifndef RNSEnums_h -#define RNSEnums_h - typedef NS_ENUM(NSInteger, RNSScreenStackPresentation) { RNSScreenStackPresentationPush, RNSScreenStackPresentationModal, @@ -60,5 +57,3 @@ typedef NS_ENUM(NSInteger, RNSScreenStackHeaderSubviewType) { RNSScreenStackHeaderSubviewTypeCenter, RNSScreenStackHeaderSubviewTypeSearchBar, }; - -#endif /* RNSEnums_h */ From 4e364397a17b95285d0eacf02aadfd8133b584e5 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 08:52:28 +0200 Subject: [PATCH 136/156] refact: remove unused addSubviewsToNavItem:withConfig: method This method is not exposed in class interface --- ios/RNSScreenStackHeaderConfig.mm | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index ce54e12b06..f048024b17 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -628,36 +628,6 @@ + (void)updateViewController:(UIViewController *)vc #ifdef RN_FABRIC_ENABLED #pragma mark - Fabric specific -+ (void)addSubviewsToNavItem:(UINavigationItem *)navitem withConfig:(RNSScreenStackHeaderConfig *)config -{ - for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { - switch (subview.type) { - case RNSScreenStackHeaderSubviewTypeLeft: { - UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; - navitem.leftBarButtonItem = buttonItem; - break; - } - case RNSScreenStackHeaderSubviewTypeRight: { - UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; - navitem.rightBarButtonItem = buttonItem; - break; - } - case RNSScreenStackHeaderSubviewTypeCenter: - case RNSScreenStackHeaderSubviewTypeTitle: { - navitem.titleView = subview; - break; - } - case RNSScreenStackHeaderSubviewTypeSearchBar: { - RCTLogWarn(@"SearchBar is not yet supported in react-native-screens with Fabric enabled"); - break; - } - case RNSScreenStackHeaderSubviewTypeBackButton: { - break; - } - } - } -} - - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { if (![childComponentView isKindOfClass:[RNSScreenStackHeaderSubview class]]) { From 1c50971822aed96d903ebe9533e232316c7e4c60 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 09:08:52 +0200 Subject: [PATCH 137/156] chore: surround RNSScreenStackHeaderSubviewCls method with guard directives RCTComponentViewProtocol is not available on paper --- ios/RNSScreenStackHeaderSubview.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ios/RNSScreenStackHeaderSubview.mm b/ios/RNSScreenStackHeaderSubview.mm index d7dc30173e..0294034c61 100644 --- a/ios/RNSScreenStackHeaderSubview.mm +++ b/ios/RNSScreenStackHeaderSubview.mm @@ -107,10 +107,12 @@ - (UIView *)view @end +#ifdef RN_FABRIC_ENABLED Class RNSScreenStackHeaderSubviewCls(void) { return RNSScreenStackHeaderSubview.class; } +#endif @implementation RCTConvert (RNSScreenStackHeaderSubview) From b914e28602e1f94636ca9b2209c4f023b5d852b4 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 09:10:38 +0200 Subject: [PATCH 138/156] refact: change #ifndef to #ifdef #else ... --- ios/RNSScreenStackHeaderSubview.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ios/RNSScreenStackHeaderSubview.h b/ios/RNSScreenStackHeaderSubview.h index 79b4c37596..973e82df58 100644 --- a/ios/RNSScreenStackHeaderSubview.h +++ b/ios/RNSScreenStackHeaderSubview.h @@ -20,7 +20,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) RNSScreenStackHeaderSubviewType type; -#ifndef RN_FABRIC_ENABLED +#ifdef RN_FABRIC_ENABLED +#else @property (nonatomic, weak) UIView *reactSuperview; #endif From e06f91636c1b03990f18a07be0aabd3a228909df Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 09:46:46 +0200 Subject: [PATCH 139/156] refact: remove leftover comments --- ios/RNSScreenStack.mm | 9 --------- 1 file changed, 9 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 08bb403abb..c998600f28 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -219,7 +219,6 @@ - (void)didMoveToWindow #endif } -// done - (void)maybeAddToParentAndUpdateContainer { BOOL wasScreenMounted = _controller.parentViewController != nil; @@ -255,7 +254,6 @@ - (void)maybeAddToParentAndUpdateContainer } } -// done - (void)reactAddControllerToClosestParent:(UIViewController *)controller { if (!controller.parentViewController) { @@ -283,7 +281,6 @@ - (void)reactAddControllerToClosestParent:(UIViewController *)controller } } -// done - (void)setModalViewControllers:(NSArray *)controllers { // prevent re-entry @@ -419,7 +416,6 @@ - (void)setModalViewControllers:(NSArray *)controllers } } -// done - (void)setPushViewControllers:(NSArray *)controllers { // when there is no change we return immediately @@ -514,7 +510,6 @@ - (void)setPushViewControllers:(NSArray *)controllers } } -// done - (void)updateContainer { NSMutableArray *pushControllers = [NSMutableArray new]; @@ -563,7 +558,6 @@ - (void)dismissOnReload #pragma mark methods connected to transitioning -// done - (id)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC @@ -607,7 +601,6 @@ - (void)cancelTouchesInParent } } -// done - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view; @@ -680,7 +673,6 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer } #if !TARGET_OS_TV -// done - (void)setupGestureHandlers { // gesture recognizers for custom stack animations @@ -703,7 +695,6 @@ - (void)setupGestureHandlers [self addGestureRecognizer:panRecognizer]; } -// done - (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer { RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view; From 6255f2e0a8eaa9c254f6042c585da11152e8c750 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 10:30:03 +0200 Subject: [PATCH 140/156] fix: revert c03b80903 There are references to subview.bridge in RNSScreenStackHeaderConfig methods https://github.com/software-mansion/react-native-screens/pull/1418/commits/c03b80903c098f0cf3ea0ae7b3281b84e6db2a27 --- ios/RNSScreenStackHeaderSubview.h | 4 ++++ ios/RNSScreenStackHeaderSubview.mm | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/ios/RNSScreenStackHeaderSubview.h b/ios/RNSScreenStackHeaderSubview.h index 973e82df58..a753160ae3 100644 --- a/ios/RNSScreenStackHeaderSubview.h +++ b/ios/RNSScreenStackHeaderSubview.h @@ -23,6 +23,10 @@ NS_ASSUME_NONNULL_BEGIN #ifdef RN_FABRIC_ENABLED #else @property (nonatomic, weak) UIView *reactSuperview; +@property (nonatomic, weak) RCTBridge *bridge; + +- (instancetype)initWithBridge:(RCTBridge *)bridge; + #endif @end diff --git a/ios/RNSScreenStackHeaderSubview.mm b/ios/RNSScreenStackHeaderSubview.mm index 0294034c61..897ebc302f 100644 --- a/ios/RNSScreenStackHeaderSubview.mm +++ b/ios/RNSScreenStackHeaderSubview.mm @@ -84,6 +84,14 @@ - (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetric #else #pragma mark - Paper specific +- (instancetype)initWithBridge:(RCTBridge *)bridge +{ + if (self = [super init]) { + _bridge = bridge; + } + return self; +} + - (void)reactSetFrame:(CGRect)frame { // Block any attempt to set coordinates on RNSScreenStackHeaderSubview. This @@ -102,7 +110,7 @@ @implementation RNSScreenStackHeaderSubviewManager - (UIView *)view { - return [RNSScreenStackHeaderSubview new]; + return [[RNSScreenStackHeaderSubview alloc] initWithBridge:self.bridge]; } @end From 8e16be2c3c6eec02788726a7c73d3e5ccc551ee2 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 10:46:44 +0200 Subject: [PATCH 141/156] refact: remove // done comments for the 3rd time... --- ios/RNSScreenStack.mm | 9 --------- 1 file changed, 9 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 08bb403abb..c998600f28 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -219,7 +219,6 @@ - (void)didMoveToWindow #endif } -// done - (void)maybeAddToParentAndUpdateContainer { BOOL wasScreenMounted = _controller.parentViewController != nil; @@ -255,7 +254,6 @@ - (void)maybeAddToParentAndUpdateContainer } } -// done - (void)reactAddControllerToClosestParent:(UIViewController *)controller { if (!controller.parentViewController) { @@ -283,7 +281,6 @@ - (void)reactAddControllerToClosestParent:(UIViewController *)controller } } -// done - (void)setModalViewControllers:(NSArray *)controllers { // prevent re-entry @@ -419,7 +416,6 @@ - (void)setModalViewControllers:(NSArray *)controllers } } -// done - (void)setPushViewControllers:(NSArray *)controllers { // when there is no change we return immediately @@ -514,7 +510,6 @@ - (void)setPushViewControllers:(NSArray *)controllers } } -// done - (void)updateContainer { NSMutableArray *pushControllers = [NSMutableArray new]; @@ -563,7 +558,6 @@ - (void)dismissOnReload #pragma mark methods connected to transitioning -// done - (id)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC @@ -607,7 +601,6 @@ - (void)cancelTouchesInParent } } -// done - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view; @@ -680,7 +673,6 @@ - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer } #if !TARGET_OS_TV -// done - (void)setupGestureHandlers { // gesture recognizers for custom stack animations @@ -703,7 +695,6 @@ - (void)setupGestureHandlers [self addGestureRecognizer:panRecognizer]; } -// done - (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer { RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view; From 9ec99bc7fae5df5a2faa2fcd90fb80e7fd59acba Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 10:48:23 +0200 Subject: [PATCH 142/156] refact: ifndef -> ifdef + else (for the 3rd time) merge artifacts! --- ios/RNSScreenStack.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index c998600f28..56fd8db1f6 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -265,7 +265,8 @@ - (void)reactAddControllerToClosestParent:(UIViewController *)controller #if !TARGET_OS_TV _controller.interactivePopGestureRecognizer.delegate = self; #endif -#ifndef RN_FABRIC_ENABLED +#ifdef RN_FABRIC_ENABLED +#else [controller didMoveToParentViewController:parentView.reactViewController]; #endif // On iOS pre 12 we observed that `willShowViewController` delegate method does not always @@ -994,7 +995,8 @@ @implementation RNSScreenStackManager { RCT_EXPORT_VIEW_PROPERTY(onFinishTransitioning, RCTDirectEventBlock); -#ifndef RN_FABRIC_ENABLED +#ifdef RN_FABRIC_ENABLED +#else - (UIView *)view { RNSScreenStackView *view = [[RNSScreenStackView alloc] initWithManager:self]; From 1e307737c0acd60cd2ba42f778d08044dae8c7e0 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 10:50:23 +0200 Subject: [PATCH 143/156] refact: remove merge artifact: unused import --- ios/RNSScreenStack.mm | 4 +--- ios/RNSScreenStackHeaderConfig.h | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 56fd8db1f6..1ede9096cf 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -1,17 +1,15 @@ #ifdef RN_FABRIC_ENABLED #import - #import #import #import #import #import +#import #import "RCTFabricComponentsPlugins.h" -#import #else - #import #import #import diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h index 1b22c005f9..3a9ec01762 100644 --- a/ios/RNSScreenStackHeaderConfig.h +++ b/ios/RNSScreenStackHeaderConfig.h @@ -1,6 +1,5 @@ #ifdef RN_FABRIC_ENABLED #import -#import #import "RNSScreenStackHeaderSubviewComponentView.h" #else #import From 0a11a105d051805b4fa75ec13a4915aa0fa8bb8e Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 08:37:55 +0200 Subject: [PATCH 144/156] chore: move reactSubviews prop to common section in header file also remove redeclaration in implementation --- ios/RNSScreenStackHeaderConfig.h | 3 +-- ios/RNSScreenStackHeaderConfig.mm | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h index 3a9ec01762..b01f22c471 100644 --- a/ios/RNSScreenStackHeaderConfig.h +++ b/ios/RNSScreenStackHeaderConfig.h @@ -18,10 +18,9 @@ #endif @property (nonatomic, weak) RNSScreenView *screenView; +@property (nonatomic) NSMutableArray *reactSubviews; #ifdef RN_FABRIC_ENABLED -// TODO: change type when StackHeaderSubview is merged (??) -@property (nonatomic) NSMutableArray *reactSubviews; @property (nonatomic) BOOL show; #else @property (nonatomic) UIBlurEffectStyle blurEffect; diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index c4c68ca6d8..750a8cbba2 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -68,7 +68,6 @@ - (void)reactSetFrame:(CGRect)frame @implementation RNSScreenStackHeaderConfig { #ifdef RN_FABRIC_ENABLED BOOL _initialPropsSet; - NSMutableArray *_reactSubviews; facebook::react::SharedColor _backgroundSharedColor; #else NSMutableArray *_reactSubviews; From 68435f27ca31c9b9f4452ae2e0efb25155ecc92f Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 11:02:42 +0200 Subject: [PATCH 145/156] refact: linter suggestion --- ios/RNSScreenStack.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 1ede9096cf..85f44ef0cd 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -1,11 +1,11 @@ #ifdef RN_FABRIC_ENABLED #import +#import #import #import #import #import #import -#import #import "RCTFabricComponentsPlugins.h" From b917b68cbbd13cbae4aa918ea68877baef93ebb1 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 11:06:16 +0200 Subject: [PATCH 146/156] fix: make reactSubviews prop fabric specific This is changed when ScreenStackHeaderSubview is merged --- ios/RNSScreenStackHeaderConfig.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h index b01f22c471..3a9ec01762 100644 --- a/ios/RNSScreenStackHeaderConfig.h +++ b/ios/RNSScreenStackHeaderConfig.h @@ -18,9 +18,10 @@ #endif @property (nonatomic, weak) RNSScreenView *screenView; -@property (nonatomic) NSMutableArray *reactSubviews; #ifdef RN_FABRIC_ENABLED +// TODO: change type when StackHeaderSubview is merged (??) +@property (nonatomic) NSMutableArray *reactSubviews; @property (nonatomic) BOOL show; #else @property (nonatomic) UIBlurEffectStyle blurEffect; From 68187987c0a9dd767ad4df46d25bd205fc0781f1 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 11:15:11 +0200 Subject: [PATCH 147/156] refact: optimize imports --- ios/RNSScreenStackHeaderConfig.mm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 750a8cbba2..daa3590585 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -1,6 +1,5 @@ #ifdef RN_FABRIC_ENABLED #import -#import #import #import #import @@ -11,7 +10,6 @@ #else // TODO: move this import when SearchBar is implemented on Fabric #import -#import #import #import #import @@ -20,7 +18,8 @@ #import #import "RNSSearchBar.h" #endif -#import "./utils/RNSUIBarButtonItem.h" +#import +#import "RNSUIBarButtonItem.h" #import "RNSScreen.h" #import "RNSScreenStackHeaderConfig.h" From 91ccf271607838bd1f02ce27cb30424dc13033c2 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 11:21:25 +0200 Subject: [PATCH 148/156] refact: remove unnecessary _backgroundSharedColor property --- ios/RNSScreenStackHeaderConfig.mm | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index daa3590585..abf7d6cf90 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -67,7 +67,6 @@ - (void)reactSetFrame:(CGRect)frame @implementation RNSScreenStackHeaderConfig { #ifdef RN_FABRIC_ENABLED BOOL _initialPropsSet; - facebook::react::SharedColor _backgroundSharedColor; #else NSMutableArray *_reactSubviews; #endif @@ -838,11 +837,7 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props _titleColor = RCTUIColorFromSharedColor(newScreenProps.titleColor); _largeTitleColor = RCTUIColorFromSharedColor(newScreenProps.largeTitleColor); _color = RCTUIColorFromSharedColor(newScreenProps.color); - - if (_backgroundSharedColor != newScreenProps.backgroundColor) { - _backgroundSharedColor = newScreenProps.backgroundColor; - _backgroundColor = RCTUIColorFromSharedColor(_backgroundSharedColor); - } + _backgroundColor = RCTUIColorFromSharedColor(newScreenProps.backgroundColor); [self updateViewControllerIfNeeded]; From 7460d71e41db4de7fa208258d19628dbbcddf67b Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 11:30:08 +0200 Subject: [PATCH 149/156] chore: move call to didMoveToParentViewController to common section --- ios/RNSScreenStack.mm | 3 --- 1 file changed, 3 deletions(-) diff --git a/ios/RNSScreenStack.mm b/ios/RNSScreenStack.mm index 85f44ef0cd..5a0e37d0d0 100644 --- a/ios/RNSScreenStack.mm +++ b/ios/RNSScreenStack.mm @@ -263,10 +263,7 @@ - (void)reactAddControllerToClosestParent:(UIViewController *)controller #if !TARGET_OS_TV _controller.interactivePopGestureRecognizer.delegate = self; #endif -#ifdef RN_FABRIC_ENABLED -#else [controller didMoveToParentViewController:parentView.reactViewController]; -#endif // On iOS pre 12 we observed that `willShowViewController` delegate method does not always // get triggered when the navigation controller is instantiated. As the only thing we do in // that delegate method is ask nav header to update to the current state it does not hurt to From c3ef14e86338108279e561c815229a75413c2d22 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 11:43:09 +0200 Subject: [PATCH 150/156] fix: surround RNSScreenStackHeaderSubviewManager#view method with guard directives --- ios/RNSScreenStackHeaderSubview.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ios/RNSScreenStackHeaderSubview.mm b/ios/RNSScreenStackHeaderSubview.mm index 897ebc302f..d3f41b80d2 100644 --- a/ios/RNSScreenStackHeaderSubview.mm +++ b/ios/RNSScreenStackHeaderSubview.mm @@ -108,10 +108,13 @@ @implementation RNSScreenStackHeaderSubviewManager RCT_EXPORT_VIEW_PROPERTY(type, RNSScreenStackHeaderSubviewType) +#ifdef RN_FABRIC_ENABLED +#else - (UIView *)view { return [[RNSScreenStackHeaderSubview alloc] initWithBridge:self.bridge]; } +#endif @end From 752987e82d88d052da156179424f16f838e623a7 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 11:50:27 +0200 Subject: [PATCH 151/156] chore: make reactSubviews prop private --- ios/RNSScreenStackHeaderConfig.h | 1 - ios/RNSScreenStackHeaderConfig.mm | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ios/RNSScreenStackHeaderConfig.h b/ios/RNSScreenStackHeaderConfig.h index 2d4089e7d7..3f05cc2506 100644 --- a/ios/RNSScreenStackHeaderConfig.h +++ b/ios/RNSScreenStackHeaderConfig.h @@ -19,7 +19,6 @@ #endif @property (nonatomic, weak) RNSScreenView *screenView; -@property (nonatomic) NSMutableArray *reactSubviews; #ifdef RN_FABRIC_ENABLED @property (nonatomic) BOOL show; diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index f048024b17..77b5736d6d 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -36,6 +36,7 @@ @interface RCTImageLoader (Private) #endif @implementation RNSScreenStackHeaderConfig { + NSMutableArray *_reactSubviews; #ifdef RN_FABRIC_ENABLED BOOL _initialPropsSet; facebook::react::SharedColor _backgroundSharedColor; From b0f1141666ca2b7ef55d5f660a3f855bef7970d5 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 11:55:06 +0200 Subject: [PATCH 152/156] refact: minor changes --- ios/RNSScreenStackHeaderConfig.mm | 1 - ios/RNSScreenStackHeaderSubview.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 77b5736d6d..e24f6e966a 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -590,7 +590,6 @@ + (void)updateViewController:(UIViewController *)vc RCTLogWarn(@"Back button subivew is not yet Fabric compatible in react-native-screens"); #endif break; - ; } } } diff --git a/ios/RNSScreenStackHeaderSubview.h b/ios/RNSScreenStackHeaderSubview.h index a753160ae3..ff75b984c9 100644 --- a/ios/RNSScreenStackHeaderSubview.h +++ b/ios/RNSScreenStackHeaderSubview.h @@ -1,8 +1,6 @@ #ifdef RN_FABRIC_ENABLED #import -#import -#import #endif #import From 4ca37ef5e616be7c21f243ed3f370cc08a474ae9 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 11:58:03 +0200 Subject: [PATCH 153/156] chore: remove unused private isInitialValueSet prop --- ios/RNSScreenStackHeaderSubview.mm | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/ios/RNSScreenStackHeaderSubview.mm b/ios/RNSScreenStackHeaderSubview.mm index d3f41b80d2..5d0ead1f48 100644 --- a/ios/RNSScreenStackHeaderSubview.mm +++ b/ios/RNSScreenStackHeaderSubview.mm @@ -10,11 +10,7 @@ #import "RCTFabricComponentsPlugins.h" #endif -@implementation RNSScreenStackHeaderSubview { -#ifdef RN_FABRIC_ENABLED - BOOL _isInitialValueSet; -#endif -} +@implementation RNSScreenStackHeaderSubview #pragma mark - Common @@ -37,7 +33,6 @@ - (instancetype)initWithFrame:(CGRect)frame - (void)prepareForRecycle { [super prepareForRecycle]; - _isInitialValueSet = NO; } - (void)updateProps:(facebook::react::Props::Shared const &)props @@ -50,7 +45,6 @@ - (void)updateProps:(facebook::react::Props::Shared const &)props if (newHeaderSubviewProps.type != oldHeaderSubviewProps.type) { _type = [RNSConvert RNSScreenStackHeaderSubviewTypeFromCppEquivalent:newHeaderSubviewProps.type]; - _isInitialValueSet = YES; } [super updateProps:props oldProps:oldProps]; From b59a975a49d0a34acb663bbe983fcd938520456b Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 14:16:04 +0200 Subject: [PATCH 154/156] refact: remove duplicated for loop This was already done in previous commit, but it somehow came back after merging base branches. --- ios/RNSScreenStackHeaderConfig.mm | 38 +++---------------------------- 1 file changed, 3 insertions(+), 35 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 3efa722fac..afe1b4ea0c 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -555,43 +555,12 @@ + (void)updateViewController:(UIViewController *)vc navitem.leftBarButtonItem = nil; navitem.rightBarButtonItem = nil; navitem.titleView = nil; -#ifdef RN_FABRIC_ENABLED - for (RNSScreenStackHeaderSubviewComponentView *subview in config.reactSubviews) { - switch (subview.type) { - case facebook::react::RNSScreenStackHeaderSubviewType::Left: { - //#if !TARGET_OS_TV - // navitem.leftItemsSupplementBackButton = config.backButtonInCustomView; - //#endif - UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; - navitem.leftBarButtonItem = buttonItem; - break; - } - case facebook::react::RNSScreenStackHeaderSubviewType::Right: { - UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:subview]; - navitem.rightBarButtonItem = buttonItem; - break; - } - case facebook::react::RNSScreenStackHeaderSubviewType::Center: - case facebook::react::RNSScreenStackHeaderSubviewType::Title: { - navitem.titleView = subview; - break; - } - case facebook::react::RNSScreenStackHeaderSubviewType::SearchBar: { - RCTLogWarn(@"SearchBar is not yet Fabric compatible in react-native-screens"); - break; - } - case facebook::react::RNSScreenStackHeaderSubviewType::Back: { - RCTLogWarn(@"Back button subivew is not yet Fabric compatible in react-native-screens"); - break; - ; - } - } - } -#else + for (RNSScreenStackHeaderSubview *subview in config.reactSubviews) { switch (subview.type) { case RNSScreenStackHeaderSubviewTypeLeft: { -#ifndef RN_FABRIC_ENABLED +#ifdef RN_FABRIC_ENABLED +#else #if !TARGET_OS_TV navitem.leftItemsSupplementBackButton = config.backButtonInCustomView; #endif @@ -642,7 +611,6 @@ + (void)updateViewController:(UIViewController *)vc } } } -#endif // RN_FABRIC_ENABLED if (animated && vc.transitionCoordinator != nil && vc.transitionCoordinator.presentationStyle == UIModalPresentationNone && !wasHidden) { From ad5e7d40a90aa52ef66f6b34f677968d0a1f6453 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 14:19:41 +0200 Subject: [PATCH 155/156] chore: merge RNSScreenStackHeaderConfig#hitTest:withEvent: method This was already done in 076be9854f6a94 (https://github.com/software-mansion/react-native-screens/pull/1418/commits/076be9854f6a946232d8704aff8bc79f6862a335) Merging base branches bringed it back. --- ios/RNSScreenStackHeaderConfig.mm | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index afe1b4ea0c..356d9273eb 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -87,23 +87,6 @@ - (void)removeFromSuperview // is not added to native view hierarchy so we can apply our logic - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { -#ifdef RN_FABRIC_ENABLED - for (RNSScreenStackHeaderSubviewComponentView *subview in _reactSubviews) { - if (subview.type == facebook::react::RNSScreenStackHeaderSubviewType::Left || - subview.type == facebook::react::RNSScreenStackHeaderSubviewType::Right) { - // we wrap the headerLeft/Right component in a UIBarButtonItem - // so we need to use the only subview of it to retrieve the correct view - UIView *headerComponent = subview.subviews.firstObject; - // we convert the point to RNSScreenStackView since it always contains the header inside it - CGPoint convertedPoint = [_screenView.reactSuperview convertPoint:point toView:headerComponent]; - - UIView *hitTestResult = [headerComponent hitTest:convertedPoint withEvent:event]; - if (hitTestResult != nil) { - return hitTestResult; - } - } - } -#else for (RNSScreenStackHeaderSubview *subview in _reactSubviews) { if (subview.type == RNSScreenStackHeaderSubviewTypeLeft || subview.type == RNSScreenStackHeaderSubviewTypeRight) { // we wrap the headerLeft/Right component in a UIBarButtonItem @@ -118,7 +101,6 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event } } } -#endif return nil; } From 29a5f9fc5d63261ad1ce5889ef9ef967fb9ad152 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 28 Apr 2022 14:28:37 +0200 Subject: [PATCH 156/156] refact: cleanup --- ios/RNSScreenStackHeaderConfig.mm | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ios/RNSScreenStackHeaderConfig.mm b/ios/RNSScreenStackHeaderConfig.mm index 356d9273eb..3d589d306f 100644 --- a/ios/RNSScreenStackHeaderConfig.mm +++ b/ios/RNSScreenStackHeaderConfig.mm @@ -22,7 +22,8 @@ #import "RNSScreen.h" #import "RNSScreenStackHeaderConfig.h" -#ifndef RN_FABRIC_ENABLED +#ifdef RN_FABRIC_ENABLED +#else // Some RN private method hacking below. Couldn't figure out better way to access image data // of a given RCTImageView. See more comments in the code section processing SubviewTypeBackButton @interface RCTImageView (Private) @@ -343,7 +344,8 @@ + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc } // TODO: implement blurEffect on Fabric -#ifndef RN_FABRIC_ENABLED +#ifdef RN_FABRIC_ENABLED +#else if (config.blurEffect) { appearance.backgroundEffect = [UIBlurEffect effectWithStyle:config.blurEffect]; } @@ -403,15 +405,15 @@ + (UINavigationBarAppearance *)buildAppearance:(UIViewController *)vc appearance.largeTitleTextAttributes = largeAttrs; } -#ifndef RN_FABRIC_ENABLED +#ifdef RN_FABRIC_ENABLED + [appearance setBackIndicatorImage:nil transitionMaskImage:nil]; +#else UIImage *backButtonImage = [self loadBackButtonImageInViewController:vc withConfig:config]; if (backButtonImage) { [appearance setBackIndicatorImage:backButtonImage transitionMaskImage:backButtonImage]; } else if (appearance.backIndicatorImage) { [appearance setBackIndicatorImage:nil transitionMaskImage:nil]; } -#else - [appearance setBackIndicatorImage:nil transitionMaskImage:nil]; #endif // RN_FABRIC_ENABLED return appearance; }