Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NavigationReactNative/src/NavigationStack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ const NavigationStack = ({underlayColor: underlayColorStack = '#000', title, cus
fragmentTag={fragmentTag}
ancestorFragmentTags={ancestorFragmentTags}
mostRecentEventCount={mostRecentEventCount}
customAnimation={customAnimation}
style={styles.stack}
{...getAnimation()}
onWillNavigateBack={onWillNavigateBack}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type NativeProps = $ReadOnly<{|
enterAnimOff: boolean,
sharedElements: $ReadOnlyArray<string>,
containerTransform: boolean,
customAnimation: boolean,
underlayColor: ColorValue,
mostRecentEventCount: Int32,
onNavigateToTop: DirectEventHandler<null>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ public void setContainerTransform(NavigationStackView view, boolean containerTra
view.containerTransform = containerTransform;
}

@Override
public void setCustomAnimation(NavigationStackView view, boolean value) {
}

@Override
public void setUnderlayColor(NavigationStackView view, @Nullable Integer value) {
}
Expand Down
39 changes: 30 additions & 9 deletions NavigationReactNative/src/ios/NVNavigationStackComponentView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#import "NVSceneTransitioning.h"
#import "NVSharedElementComponentView.h"
#import "NVNavigationBarComponentView.h"
#import "NVStackControllerDelegate.h"

#import <react/renderer/components/navigationreactnative/ComponentDescriptors.h>
#import <react/renderer/components/navigationreactnative/EventEmitters.h>
Expand All @@ -34,6 +35,8 @@ @implementation NVNavigationStackComponentView
UIScreenEdgePanGestureRecognizer *_interactiveGestureRecognizer;
UIPanGestureRecognizer *_interactiveContentGestureRecognizer;
UIPercentDrivenInteractiveTransition *_interactiveTransition;
NVStackControllerDelegate *_stackControllerDelegate;
id<UIGestureRecognizerDelegate> _interactiveGestureRecognizerDelegate;
BOOL _navigated;
BOOL _presenting;
}
Expand All @@ -50,18 +53,14 @@ - (instancetype)initWithFrame:(CGRect)frame
_navigationController.view.semanticContentAttribute = ![[RCTI18nUtil sharedInstance] isRTL] ? UISemanticContentAttributeForceLeftToRight : UISemanticContentAttributeForceRightToLeft;
_navigationController.navigationBar.semanticContentAttribute = ![[RCTI18nUtil sharedInstance] isRTL] ? UISemanticContentAttributeForceLeftToRight : UISemanticContentAttributeForceRightToLeft;
[self addSubview:_navigationController.view];
_navigationController.delegate = self;
_navigationController.interactivePopGestureRecognizer.delegate = self;
_stackControllerDelegate = [[NVStackControllerDelegate alloc] initWithStackView:self];
_navigationController.delegate = _stackControllerDelegate;
_interactiveGestureRecognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleInteractivePopGesture:)];
_interactiveGestureRecognizer.delegate = self;
_interactiveGestureRecognizerDelegate = _navigationController.interactivePopGestureRecognizer.delegate;
_interactiveGestureRecognizer.edges = ![[RCTI18nUtil sharedInstance] isRTL] ? UIRectEdgeLeft : UIRectEdgeRight;
[_navigationController.view addGestureRecognizer:_interactiveGestureRecognizer];
if (@available(iOS 26.0, *)) {
_navigationController.interactiveContentPopGestureRecognizer.delegate = self;
_interactiveContentGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleInteractivePopGesture:)];
_interactiveContentGestureRecognizer.delegate = self;
[_navigationController.view addGestureRecognizer:_interactiveContentGestureRecognizer];
}
_interactiveContentGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleInteractivePopGesture:)];
_interactiveContentGestureRecognizer.delegate = self;
}
return self;
}
Expand Down Expand Up @@ -111,6 +110,28 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
[_exitTransitions addObject:transition];
}
_sharedElement = newViewProps.sharedElements.size() > 0 ? [NSString stringWithUTF8String: newViewProps.sharedElements[0].c_str()] : nil;
if (newViewProps.customAnimation) {
if (_navigationController.interactivePopGestureRecognizer.delegate != self) {
_stackControllerDelegate = [[NVStackControllerTransitionDelegate alloc] initWithStackView:self];
_navigationController.delegate = _stackControllerDelegate;
_navigationController.interactivePopGestureRecognizer.delegate = self;
[_navigationController.view addGestureRecognizer:_interactiveGestureRecognizer];
if (@available(iOS 26.0, *)) {
_navigationController.interactiveContentPopGestureRecognizer.delegate = self;
[_navigationController.view addGestureRecognizer:_interactiveContentGestureRecognizer];
}
}
} else {
if (_navigationController.interactivePopGestureRecognizer.delegate == self) {
_stackControllerDelegate = [[NVStackControllerDelegate alloc] initWithStackView:self];
_navigationController.delegate = _stackControllerDelegate;
[_navigationController.view removeGestureRecognizer:_interactiveGestureRecognizer];
[_navigationController.view removeGestureRecognizer:_interactiveContentGestureRecognizer];
_navigationController.interactivePopGestureRecognizer.delegate = _interactiveGestureRecognizerDelegate;
if (@available(iOS 26.0, *))
_navigationController.interactiveContentPopGestureRecognizer.delegate = _interactiveGestureRecognizerDelegate;
}
}
_navigationController.view.backgroundColor = RCTUIColorFromSharedColor(newViewProps.underlayColor);
_mostRecentEventCount = newViewProps.mostRecentEventCount;
if (!_navigated) {
Expand Down
1 change: 1 addition & 0 deletions NavigationReactNative/src/ios/NVNavigationStackManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(enterAnimOff, BOOL)
RCT_EXPORT_VIEW_PROPERTY(enterTrans, NSDictionary)
RCT_EXPORT_VIEW_PROPERTY(exitTrans, NSDictionary)
RCT_EXPORT_VIEW_PROPERTY(customAnimation, BOOL)
RCT_EXPORT_VIEW_PROPERTY(sharedElements, NSArray)
RCT_EXPORT_VIEW_PROPERTY(underlayColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(mostRecentEventCount, NSInteger)
Expand Down
43 changes: 34 additions & 9 deletions NavigationReactNative/src/ios/NVNavigationStackView.m
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#import "NVSceneTransitioning.h"
#import "NVSharedElementView.h"
#import "NVNavigationBarView.h"
#import "NVStackControllerDelegate.h"

#import <UIKit/UIKit.h>
#import <React/RCTBridge.h>
Expand All @@ -23,6 +24,8 @@ @implementation NVNavigationStackView
UIScreenEdgePanGestureRecognizer *_interactiveGestureRecognizer;
UIPanGestureRecognizer *_interactiveContentGestureRecognizer;
UIPercentDrivenInteractiveTransition *_interactiveTransition;
NVStackControllerDelegate *_stackControllerDelegate;
id<UIGestureRecognizerDelegate> _interactiveGestureRecognizerDelegate;
BOOL _navigated;
BOOL _presenting;
}
Expand All @@ -35,18 +38,14 @@ - (id)initWithBridge:(RCTBridge *)bridge
_navigationController.view.semanticContentAttribute = ![[RCTI18nUtil sharedInstance] isRTL] ? UISemanticContentAttributeForceLeftToRight : UISemanticContentAttributeForceRightToLeft;
_navigationController.navigationBar.semanticContentAttribute = ![[RCTI18nUtil sharedInstance] isRTL] ? UISemanticContentAttributeForceLeftToRight : UISemanticContentAttributeForceRightToLeft;
[self addSubview:_navigationController.view];
_navigationController.delegate = self;
_navigationController.interactivePopGestureRecognizer.delegate = self;
_stackControllerDelegate = [[NVStackControllerDelegate alloc] initWithStackView:self];
_navigationController.delegate = _stackControllerDelegate;
_interactiveGestureRecognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleInteractivePopGesture:)];
_interactiveGestureRecognizer.delegate = self;
_interactiveGestureRecognizerDelegate = _navigationController.interactivePopGestureRecognizer.delegate;
_interactiveGestureRecognizer.edges = ![[RCTI18nUtil sharedInstance] isRTL] ? UIRectEdgeLeft : UIRectEdgeRight;
[_navigationController.view addGestureRecognizer:_interactiveGestureRecognizer];
if (@available(iOS 26.0, *)) {
_navigationController.interactiveContentPopGestureRecognizer.delegate = self;
_interactiveContentGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleInteractivePopGesture:)];
_interactiveContentGestureRecognizer.delegate = self;
[_navigationController.view addGestureRecognizer:_interactiveContentGestureRecognizer];
}
_interactiveContentGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleInteractivePopGesture:)];
_interactiveContentGestureRecognizer.delegate = self;
_scenes = [[NSMutableDictionary alloc] init];
_enterTransitions = [[NSMutableArray alloc] init];
_exitTransitions = [[NSMutableArray alloc] init];
Expand Down Expand Up @@ -75,6 +74,32 @@ - (void)setSharedElements:(NSArray *)sharedElements
_sharedElement = [sharedElements objectAtIndex:0];
}

- (void)setCustomAnimation:(BOOL)customAnimation
{
if (customAnimation) {
if (_navigationController.interactivePopGestureRecognizer.delegate != self) {
_stackControllerDelegate = [[NVStackControllerTransitionDelegate alloc] initWithStackView:self];
_navigationController.delegate = _stackControllerDelegate;
_navigationController.interactivePopGestureRecognizer.delegate = self;
[_navigationController.view addGestureRecognizer:_interactiveGestureRecognizer];
if (@available(iOS 26.0, *)) {
_navigationController.interactiveContentPopGestureRecognizer.delegate = self;
[_navigationController.view addGestureRecognizer:_interactiveContentGestureRecognizer];
}
}
} else {
if (_navigationController.interactivePopGestureRecognizer.delegate == self) {
_stackControllerDelegate = [[NVStackControllerDelegate alloc] initWithStackView:self];
_navigationController.delegate = _stackControllerDelegate;
[_navigationController.view removeGestureRecognizer:_interactiveGestureRecognizer];
[_navigationController.view removeGestureRecognizer:_interactiveContentGestureRecognizer];
_navigationController.interactivePopGestureRecognizer.delegate = _interactiveGestureRecognizerDelegate;
if (@available(iOS 26.0, *))
_navigationController.interactiveContentPopGestureRecognizer.delegate = _interactiveGestureRecognizerDelegate;
}
}
}

- (void)setUnderlayColor:(UIColor *)underlayColor
{
_navigationController.view.backgroundColor = underlayColor;
Expand Down
11 changes: 11 additions & 0 deletions NavigationReactNative/src/ios/NVStackControllerDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#import <UIKit/UIKit.h>

@interface NVStackControllerDelegate : NSObject <UINavigationControllerDelegate>

-(id)initWithStackView: (id<UINavigationControllerDelegate>)stackView;

@end

@interface NVStackControllerTransitionDelegate : NVStackControllerDelegate

@end
55 changes: 55 additions & 0 deletions NavigationReactNative/src/ios/NVStackControllerDelegate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#import "NVStackControllerDelegate.h"

#import <UIKit/UIKit.h>


@implementation NVStackControllerDelegate
{
__weak id<UINavigationControllerDelegate> _stackView;
}

- (id)initWithStackView:(id<UINavigationControllerDelegate>)stackView
{
if (self = [super init]) {
_stackView = stackView;
}
return self;
}

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[_stackView navigationController:navigationController willShowViewController:viewController animated:animated];
}

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[_stackView navigationController:navigationController didShowViewController:viewController animated:animated];
}

@end


@implementation NVStackControllerTransitionDelegate
{
__weak id<UINavigationControllerDelegate> _stackView;
}

- (id)initWithStackView:(id<UINavigationControllerDelegate>)stackView
{
if (self = [super initWithStackView:stackView]) {
_stackView = stackView;
}
return self;
}

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
return [_stackView navigationController:navigationController animationControllerForOperation:operation fromViewController:fromVC toViewController:toVC];
}

- (id<UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id<UIViewControllerAnimatedTransitioning>)animationController
{
return [_stackView navigationController:navigationController interactionControllerForAnimationController:animationController];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@
70BB32A3212B2D4100DE0D13 /* NVBarView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NVBarView.m; sourceTree = "<group>"; };
70CCAAC42B18F9B200747AFF /* NVBottomSheetDialogComponentView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NVBottomSheetDialogComponentView.h; sourceTree = "<group>"; };
70CCAAC52B18F9C500747AFF /* NVBottomSheetDialogComponentView.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = NVBottomSheetDialogComponentView.mm; sourceTree = "<group>"; };
70DB41D82E9943F100D6D676 /* NVStackControllerDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NVStackControllerDelegate.h; sourceTree = "<group>"; };
70DB41D92E99455F00D6D676 /* NVStackControllerDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NVStackControllerDelegate.m; sourceTree = "<group>"; };
70DC9BDC2843AA930047EEF4 /* NVActionBarComponentView.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = NVActionBarComponentView.mm; sourceTree = "<group>"; };
70DC9BDD2843AAA00047EEF4 /* NVActionBarComponentView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NVActionBarComponentView.h; sourceTree = "<group>"; };
70DC9BDE2843AB800047EEF4 /* NVCollapsingBarComponentView.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = NVCollapsingBarComponentView.mm; sourceTree = "<group>"; };
Expand Down Expand Up @@ -161,6 +163,8 @@
7020F6B520ECD07A00E7A74E = {
isa = PBXGroup;
children = (
70DB41D92E99455F00D6D676 /* NVStackControllerDelegate.m */,
70DB41D82E9943F100D6D676 /* NVStackControllerDelegate.h */,
70F1854E2D04B4210094022B /* NVSharedElementManager.m */,
70F1854D2D04B40A0094022B /* NVSharedElementView.h */,
70F1854C2D04B3FF0094022B /* NVSharedElementView.m */,
Expand Down