react-native-screens 3.10.1 → 3.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +13 -7
- package/RNScreens.podspec +36 -6
- package/android/build.gradle +74 -3
- package/android/src/fabric/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +49 -0
- package/android/src/fabric/java/com/swmansion/rnscreens/RNScreensComponentsRegistry.java +28 -0
- package/android/src/main/java/com/swmansion/rnscreens/RNScreensPackage.kt +11 -2
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +52 -21
- package/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenFragment.kt +64 -33
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +9 -31
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.kt +0 -30
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.kt +12 -5
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfigViewManager.kt +83 -18
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderSubviewManager.kt +17 -5
- package/android/src/main/java/com/swmansion/rnscreens/ScreenStackViewManager.kt +14 -1
- package/android/src/main/java/com/swmansion/rnscreens/ScreenViewManager.kt +41 -14
- package/android/src/main/java/com/swmansion/rnscreens/ScreenWindowTraits.kt +72 -11
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarManager.kt +18 -1
- package/android/src/main/java/com/swmansion/rnscreens/SearchBarView.kt +7 -2
- package/android/src/main/java/com/swmansion/rnscreens/SearchViewFormatter.kt +29 -2
- package/android/src/main/jni/Android.mk +45 -0
- package/android/src/main/jni/OnLoad.cpp +9 -0
- package/android/src/main/jni/RNScreensComponentsRegistry.cpp +66 -0
- package/android/src/main/jni/RNScreensComponentsRegistry.h +34 -0
- package/android/src/main/res/anim/rns_default_enter_in.xml +18 -0
- package/android/src/main/res/anim/rns_default_enter_out.xml +19 -0
- package/android/src/main/res/anim/rns_default_exit_in.xml +17 -0
- package/android/src/main/res/anim/rns_default_exit_out.xml +18 -0
- package/android/src/main/res/anim/rns_fade_in.xml +7 -0
- package/android/src/main/res/anim/rns_fade_out.xml +7 -0
- package/android/src/main/res/anim/rns_no_animation_20.xml +6 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerDelegate.java +71 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenManagerInterface.java +30 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerDelegate.java +104 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderConfigManagerInterface.java +41 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerDelegate.java +31 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackHeaderSubviewManagerInterface.java +17 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerDelegate.java +25 -0
- package/android/src/paper/java/com/facebook/react/viewmanagers/RNSScreenStackManagerInterface.java +16 -0
- package/android/src/paper/java/com/swmansion/rnscreens/FabricEnabledViewGroup.kt +16 -0
- package/common/cpp/Android.mk +38 -0
- package/common/cpp/rnscreens/RNSScreenComponentDescriptor.h +41 -0
- package/common/cpp/rnscreens/RNSScreenShadowNode.cpp +9 -0
- package/common/cpp/rnscreens/RNSScreenShadowNode.h +29 -0
- package/common/cpp/rnscreens/RNSScreenState.cpp +14 -0
- package/common/cpp/rnscreens/RNSScreenState.h +46 -0
- package/createNativeStackNavigator/README.md +12 -0
- package/ios/RNSScreen.h +10 -0
- package/ios/RNSScreen.m +34 -0
- package/ios/RNSScreenComponentView.h +23 -0
- package/ios/RNSScreenComponentView.mm +159 -0
- package/ios/RNSScreenContainer.m +5 -0
- package/ios/RNSScreenController.h +10 -0
- package/ios/RNSScreenController.mm +79 -0
- package/ios/RNSScreenStack.m +22 -7
- package/ios/RNSScreenStackAnimator.m +45 -14
- package/ios/RNSScreenStackComponentView.h +15 -0
- package/ios/RNSScreenStackComponentView.mm +295 -0
- package/ios/RNSScreenStackHeaderConfig.m +4 -1
- package/ios/RNSScreenStackHeaderConfigComponentView.h +42 -0
- package/ios/RNSScreenStackHeaderConfigComponentView.mm +662 -0
- package/ios/RNSScreenStackHeaderSubviewComponentView.h +14 -0
- package/ios/RNSScreenStackHeaderSubviewComponentView.mm +77 -0
- package/ios/RNSScreenWindowTraits.h +1 -0
- package/ios/RNSScreenWindowTraits.m +20 -0
- package/ios/UIViewController+RNScreens.m +10 -0
- package/ios/utils/RNSUIBarButtonItem.h +5 -0
- package/ios/utils/RNSUIBarButtonItem.mm +22 -0
- package/lib/commonjs/fabric/Screen.js +27 -0
- package/lib/commonjs/fabric/Screen.js.map +1 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js +23 -0
- package/lib/commonjs/fabric/ScreenNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStack.js +27 -0
- package/lib/commonjs/fabric/ScreenStack.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js +27 -0
- package/lib/commonjs/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubview.js +34 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubview.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js +27 -0
- package/lib/commonjs/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js +21 -0
- package/lib/commonjs/fabric/ScreenStackNativeComponent.js.map +1 -0
- package/lib/commonjs/fabric/index.js +40 -0
- package/lib/commonjs/fabric/index.js.map +1 -0
- package/lib/commonjs/index.native.js +32 -15
- package/lib/commonjs/index.native.js.map +1 -1
- package/lib/commonjs/native-stack/views/NativeStackView.js +33 -4
- package/lib/commonjs/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/module/fabric/Screen.js +11 -0
- package/lib/module/fabric/Screen.js.map +1 -0
- package/lib/module/fabric/ScreenNativeComponent.js +11 -0
- package/lib/module/fabric/ScreenNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStack.js +12 -0
- package/lib/module/fabric/ScreenStack.js.map +1 -0
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js +10 -0
- package/lib/module/fabric/ScreenStackHeaderConfigNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStackHeaderSubview.js +21 -0
- package/lib/module/fabric/ScreenStackHeaderSubview.js.map +1 -0
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js +10 -0
- package/lib/module/fabric/ScreenStackHeaderSubviewNativeComponent.js.map +1 -0
- package/lib/module/fabric/ScreenStackNativeComponent.js +9 -0
- package/lib/module/fabric/ScreenStackNativeComponent.js.map +1 -0
- package/lib/module/fabric/index.js +6 -0
- package/lib/module/fabric/index.js.map +1 -0
- package/lib/module/index.native.js +32 -15
- package/lib/module/index.native.js.map +1 -1
- package/lib/module/native-stack/views/NativeStackView.js +33 -4
- package/lib/module/native-stack/views/NativeStackView.js.map +1 -1
- package/lib/typescript/native-stack/types.d.ts +34 -0
- package/lib/typescript/reanimated/ReanimatedNativeStackScreen.d.ts +1 -1
- package/lib/typescript/reanimated/ReanimatedScreen.d.ts +1 -1
- package/lib/typescript/types.d.ts +60 -5
- package/native-stack/README.md +39 -3
- package/package.json +17 -3
- package/reanimated/package.json +6 -0
- package/src/fabric/Screen.js +12 -0
- package/src/fabric/ScreenNativeComponent.js +64 -0
- package/src/fabric/ScreenStack.js +8 -0
- package/src/fabric/ScreenStackHeaderConfigNativeComponent.js +54 -0
- package/src/fabric/ScreenStackHeaderSubview.js +20 -0
- package/src/fabric/ScreenStackHeaderSubviewNativeComponent.js +31 -0
- package/src/fabric/ScreenStackNativeComponent.js +19 -0
- package/src/fabric/index.js +11 -0
- package/src/index.native.tsx +35 -14
- package/src/native-stack/types.tsx +34 -0
- package/src/native-stack/views/NativeStackView.tsx +33 -4
- package/src/types.tsx +60 -5
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
#import "RNSScreenComponentView.h"
|
|
2
|
+
#import "RNSScreenStackHeaderConfigComponentView.h"
|
|
3
|
+
|
|
4
|
+
#import <React/RCTConversions.h>
|
|
5
|
+
#import <React/RCTMountingTransactionObserving.h>
|
|
6
|
+
|
|
7
|
+
#import <react/renderer/components/rnscreens/EventEmitters.h>
|
|
8
|
+
#import <react/renderer/components/rnscreens/Props.h>
|
|
9
|
+
#import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
|
|
10
|
+
#import <rnscreens/RNSScreenComponentDescriptor.h>
|
|
11
|
+
|
|
12
|
+
#import "RCTFabricComponentsPlugins.h"
|
|
13
|
+
|
|
14
|
+
using namespace facebook::react;
|
|
15
|
+
|
|
16
|
+
@interface RNSScreenComponentView () <RCTRNSScreenViewProtocol, RCTMountingTransactionObserving>
|
|
17
|
+
@end
|
|
18
|
+
|
|
19
|
+
@implementation RNSScreenComponentView {
|
|
20
|
+
RNSScreenController *_controller;
|
|
21
|
+
RNSScreenShadowNode::ConcreteState::Shared _state;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
- (instancetype)initWithFrame:(CGRect)frame
|
|
25
|
+
{
|
|
26
|
+
if (self = [super initWithFrame:frame]) {
|
|
27
|
+
static const auto defaultProps = std::make_shared<const RNSScreenProps>();
|
|
28
|
+
_props = defaultProps;
|
|
29
|
+
_controller = [[RNSScreenController alloc] initWithView:self];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return self;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
|
|
36
|
+
{
|
|
37
|
+
[super mountChildComponentView:childComponentView index:index];
|
|
38
|
+
if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfigComponentView class]]) {
|
|
39
|
+
_config = childComponentView;
|
|
40
|
+
((RNSScreenStackHeaderConfigComponentView *)childComponentView).screenView = self;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
|
|
45
|
+
{
|
|
46
|
+
[self.controller setViewToSnapshot];
|
|
47
|
+
if ([childComponentView isKindOfClass:[RNSScreenStackHeaderConfigComponentView class]]) {
|
|
48
|
+
_config = nil;
|
|
49
|
+
}
|
|
50
|
+
[super unmountChildComponentView:childComponentView index:index];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
- (void)updateBounds
|
|
54
|
+
{
|
|
55
|
+
if (_state != nullptr) {
|
|
56
|
+
auto boundsSize = self.bounds.size;
|
|
57
|
+
auto newState = RNSScreenState{RCTSizeFromCGSize(boundsSize)};
|
|
58
|
+
_state->updateState(std::move(newState));
|
|
59
|
+
UINavigationController *navctr = _controller.navigationController;
|
|
60
|
+
[navctr.view setNeedsLayout];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
- (UIView *)reactSuperview
|
|
65
|
+
{
|
|
66
|
+
return _reactSuperview;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
- (void)notifyWillAppear
|
|
70
|
+
{
|
|
71
|
+
// If screen is already unmounted then there will be no event emitter
|
|
72
|
+
// it will be cleaned in prepareForRecycle
|
|
73
|
+
if (_eventEmitter != nullptr) {
|
|
74
|
+
std::dynamic_pointer_cast<const RNSScreenEventEmitter>(_eventEmitter)
|
|
75
|
+
->onWillAppear(RNSScreenEventEmitter::OnWillAppear{});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
- (void)notifyWillDisappear
|
|
80
|
+
{
|
|
81
|
+
// If screen is already unmounted then there will be no event emitter
|
|
82
|
+
// it will be cleaned in prepareForRecycle
|
|
83
|
+
if (_eventEmitter != nullptr) {
|
|
84
|
+
std::dynamic_pointer_cast<const RNSScreenEventEmitter>(_eventEmitter)
|
|
85
|
+
->onWillDisappear(RNSScreenEventEmitter::OnWillDisappear{});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
- (void)notifyAppear
|
|
90
|
+
{
|
|
91
|
+
// If screen is already unmounted then there will be no event emitter
|
|
92
|
+
// it will be cleaned in prepareForRecycle
|
|
93
|
+
if (_eventEmitter != nullptr) {
|
|
94
|
+
std::dynamic_pointer_cast<const RNSScreenEventEmitter>(_eventEmitter)->onAppear(RNSScreenEventEmitter::OnAppear{});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
- (void)notifyDismissedWithCount:(int)dismissCount
|
|
99
|
+
{
|
|
100
|
+
// If screen is already unmounted then there will be no event emitter
|
|
101
|
+
// it will be cleaned in prepareForRecycle
|
|
102
|
+
if (_eventEmitter != nullptr) {
|
|
103
|
+
std::dynamic_pointer_cast<const RNSScreenEventEmitter>(_eventEmitter)
|
|
104
|
+
->onDismissed(RNSScreenEventEmitter::OnDismissed{dismissCount : dismissCount});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
- (void)notifyDisappear
|
|
109
|
+
{
|
|
110
|
+
// If screen is already unmounted then there will be no event emitter
|
|
111
|
+
// it will be cleaned in prepareForRecycle
|
|
112
|
+
if (_eventEmitter != nullptr) {
|
|
113
|
+
std::dynamic_pointer_cast<const RNSScreenEventEmitter>(_eventEmitter)
|
|
114
|
+
->onDisappear(RNSScreenEventEmitter::OnDisappear{});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
#pragma mark - RCTMountingTransactionObserving
|
|
119
|
+
|
|
120
|
+
- (void)mountingTransactionWillMountWithMetadata:(MountingTransactionMetadata const &)metadata
|
|
121
|
+
{
|
|
122
|
+
[self.controller takeSnapshot];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
#pragma mark - RCTComponentViewProtocol
|
|
126
|
+
|
|
127
|
+
- (void)prepareForRecycle
|
|
128
|
+
{
|
|
129
|
+
[super prepareForRecycle];
|
|
130
|
+
// TODO: Make sure that there is no edge case when this should be uncommented
|
|
131
|
+
// _controller=nil;
|
|
132
|
+
_state.reset();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
|
136
|
+
{
|
|
137
|
+
return concreteComponentDescriptorProvider<RNSScreenComponentDescriptor>();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
|
|
141
|
+
{
|
|
142
|
+
const auto &oldScreenProps = *std::static_pointer_cast<const RNSScreenProps>(_props);
|
|
143
|
+
const auto &newScreenProps = *std::static_pointer_cast<const RNSScreenProps>(props);
|
|
144
|
+
|
|
145
|
+
[super updateProps:props oldProps:oldProps];
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
- (void)updateState:(facebook::react::State::Shared const &)state
|
|
149
|
+
oldState:(facebook::react::State::Shared const &)oldState
|
|
150
|
+
{
|
|
151
|
+
_state = std::static_pointer_cast<const RNSScreenShadowNode::ConcreteState>(state);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@end
|
|
155
|
+
|
|
156
|
+
Class<RCTComponentViewProtocol> RNSScreenCls(void)
|
|
157
|
+
{
|
|
158
|
+
return RNSScreenComponentView.class;
|
|
159
|
+
}
|
package/ios/RNSScreenContainer.m
CHANGED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
|
|
2
|
+
#import "RNSScreenComponentView.h"
|
|
3
|
+
|
|
4
|
+
@implementation RNSScreenController {
|
|
5
|
+
CGRect _lastViewFrame;
|
|
6
|
+
RNSScreenComponentView *_initialView;
|
|
7
|
+
UIView *_snapshot;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
- (instancetype)initWithView:(UIView *)view
|
|
11
|
+
{
|
|
12
|
+
if (self = [super init]) {
|
|
13
|
+
self.view = view;
|
|
14
|
+
if ([view isKindOfClass:[RNSScreenComponentView class]]) {
|
|
15
|
+
_initialView = (RNSScreenComponentView *)view;
|
|
16
|
+
} else {
|
|
17
|
+
RCTLogError(@"ScreenController can only be initialized with ScreenComponentView");
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return self;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
- (void)takeSnapshot
|
|
24
|
+
{
|
|
25
|
+
_snapshot = [self.view snapshotViewAfterScreenUpdates:NO];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
- (void)setViewToSnapshot
|
|
29
|
+
{
|
|
30
|
+
[self.view removeFromSuperview];
|
|
31
|
+
self.view = _snapshot;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
- (void)resetViewToScreen
|
|
35
|
+
{
|
|
36
|
+
[self.view removeFromSuperview];
|
|
37
|
+
self.view = _initialView;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// TODO: Find out why this is executed when screen is going out
|
|
41
|
+
- (void)viewWillAppear:(BOOL)animated
|
|
42
|
+
{
|
|
43
|
+
[super viewWillAppear:animated];
|
|
44
|
+
[_initialView notifyWillAppear];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
- (void)viewWillDisappear:(BOOL)animated
|
|
48
|
+
{
|
|
49
|
+
[super viewWillDisappear:animated];
|
|
50
|
+
[_initialView notifyWillDisappear];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
- (void)viewDidAppear:(BOOL)animated
|
|
54
|
+
{
|
|
55
|
+
[super viewDidAppear:animated];
|
|
56
|
+
[_initialView notifyAppear];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
- (void)viewDidDisappear:(BOOL)animated
|
|
60
|
+
{
|
|
61
|
+
[super viewDidDisappear:animated];
|
|
62
|
+
[_initialView notifyDisappear];
|
|
63
|
+
if (self.parentViewController == nil && self.presentingViewController == nil) {
|
|
64
|
+
// screen dismissed, send event
|
|
65
|
+
[_initialView notifyDismissedWithCount:1];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
- (void)viewDidLayoutSubviews
|
|
70
|
+
{
|
|
71
|
+
[super viewDidLayoutSubviews];
|
|
72
|
+
BOOL isDisplayedWithinUINavController = [self.parentViewController isKindOfClass:[UINavigationController class]];
|
|
73
|
+
if (isDisplayedWithinUINavController && !CGRectEqualToRect(_lastViewFrame, self.view.frame)) {
|
|
74
|
+
_lastViewFrame = self.view.frame;
|
|
75
|
+
[_initialView updateBounds];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@end
|
package/ios/RNSScreenStack.m
CHANGED
|
@@ -45,6 +45,11 @@
|
|
|
45
45
|
{
|
|
46
46
|
return [self topViewController].supportedInterfaceOrientations;
|
|
47
47
|
}
|
|
48
|
+
|
|
49
|
+
- (UIViewController *)childViewControllerForHomeIndicatorAutoHidden
|
|
50
|
+
{
|
|
51
|
+
return [self topViewController];
|
|
52
|
+
}
|
|
48
53
|
#endif
|
|
49
54
|
|
|
50
55
|
@end
|
|
@@ -645,13 +650,23 @@
|
|
|
645
650
|
|
|
646
651
|
- (void)handleSwipe:(UIPanGestureRecognizer *)gestureRecognizer
|
|
647
652
|
{
|
|
648
|
-
|
|
649
|
-
float
|
|
650
|
-
float
|
|
651
|
-
|
|
652
|
-
if (
|
|
653
|
-
translation =
|
|
654
|
-
velocity =
|
|
653
|
+
RNSScreenView *topScreen = (RNSScreenView *)_controller.viewControllers.lastObject.view;
|
|
654
|
+
float translation;
|
|
655
|
+
float velocity;
|
|
656
|
+
float distance;
|
|
657
|
+
if (topScreen.swipeDirection == RNSScreenSwipeDirectionVertical) {
|
|
658
|
+
translation = [gestureRecognizer translationInView:gestureRecognizer.view].y;
|
|
659
|
+
velocity = [gestureRecognizer velocityInView:gestureRecognizer.view].y;
|
|
660
|
+
distance = gestureRecognizer.view.bounds.size.height;
|
|
661
|
+
} else {
|
|
662
|
+
translation = [gestureRecognizer translationInView:gestureRecognizer.view].x;
|
|
663
|
+
velocity = [gestureRecognizer velocityInView:gestureRecognizer.view].x;
|
|
664
|
+
distance = gestureRecognizer.view.bounds.size.width;
|
|
665
|
+
BOOL isRTL = _controller.view.semanticContentAttribute == UISemanticContentAttributeForceRightToLeft;
|
|
666
|
+
if (isRTL) {
|
|
667
|
+
translation = -translation;
|
|
668
|
+
velocity = -velocity;
|
|
669
|
+
}
|
|
655
670
|
}
|
|
656
671
|
|
|
657
672
|
float transitionProgress = (translation / distance);
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
#import "RNSScreen.h"
|
|
3
3
|
#import "RNSScreenStack.h"
|
|
4
4
|
|
|
5
|
+
// proportions to default transition duration
|
|
6
|
+
static const float RNSSlideOpenTransitionDurationProportion = 1;
|
|
7
|
+
static const float RNSFadeOpenTransitionDurationProportion = 0.2 / 0.35;
|
|
8
|
+
static const float RNSSlideCloseTransitionDurationProportion = 0.25 / 0.35;
|
|
9
|
+
static const float RNSFadeCloseTransitionDurationProportion = 0.15 / 0.35;
|
|
10
|
+
static const float RNSFadeCloseDelayTransitionDurationProportion = 0.1 / 0.35;
|
|
11
|
+
|
|
5
12
|
@implementation RNSScreenStackAnimator {
|
|
6
13
|
UINavigationControllerOperation _operation;
|
|
7
14
|
NSTimeInterval _transitionDuration;
|
|
@@ -11,7 +18,7 @@
|
|
|
11
18
|
{
|
|
12
19
|
if (self = [super init]) {
|
|
13
20
|
_operation = operation;
|
|
14
|
-
_transitionDuration = 0.35; // default duration
|
|
21
|
+
_transitionDuration = 0.35; // default duration in seconds
|
|
15
22
|
}
|
|
16
23
|
return self;
|
|
17
24
|
}
|
|
@@ -32,6 +39,12 @@
|
|
|
32
39
|
if (screen != nil && screen.stackAnimation == RNSScreenStackAnimationNone) {
|
|
33
40
|
return 0;
|
|
34
41
|
}
|
|
42
|
+
|
|
43
|
+
if (screen != nil && screen.transitionDuration != nil && [screen.transitionDuration floatValue] >= 0) {
|
|
44
|
+
float durationInSeconds = [screen.transitionDuration floatValue] / 1000.0;
|
|
45
|
+
return durationInSeconds;
|
|
46
|
+
}
|
|
47
|
+
|
|
35
48
|
return _transitionDuration;
|
|
36
49
|
}
|
|
37
50
|
|
|
@@ -184,14 +197,30 @@
|
|
|
184
197
|
} else if (_operation == UINavigationControllerOperationPop) {
|
|
185
198
|
toViewController.view.transform = CGAffineTransformIdentity;
|
|
186
199
|
[[transitionContext containerView] insertSubview:toViewController.view belowSubview:fromViewController.view];
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
200
|
+
|
|
201
|
+
void (^animationBlock)(void) = ^{
|
|
202
|
+
toViewController.view.transform = CGAffineTransformIdentity;
|
|
203
|
+
fromViewController.view.transform = topBottomTransform;
|
|
204
|
+
};
|
|
205
|
+
void (^completionBlock)(BOOL) = ^(BOOL finished) {
|
|
206
|
+
if (transitionContext.transitionWasCancelled) {
|
|
207
|
+
toViewController.view.transform = CGAffineTransformIdentity;
|
|
208
|
+
}
|
|
209
|
+
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
if (!transitionContext.isInteractive) {
|
|
213
|
+
[UIView animateWithDuration:[self transitionDuration:transitionContext]
|
|
214
|
+
animations:animationBlock
|
|
215
|
+
completion:completionBlock];
|
|
216
|
+
} else {
|
|
217
|
+
// we don't want the EaseInOut option when swiping to dismiss the view, it is the same in default animation option
|
|
218
|
+
[UIView animateWithDuration:[self transitionDuration:transitionContext]
|
|
219
|
+
delay:0.0
|
|
220
|
+
options:UIViewAnimationOptionCurveLinear
|
|
221
|
+
animations:animationBlock
|
|
222
|
+
completion:completionBlock];
|
|
223
|
+
}
|
|
195
224
|
}
|
|
196
225
|
}
|
|
197
226
|
|
|
@@ -202,6 +231,8 @@
|
|
|
202
231
|
CGAffineTransform topBottomTransform =
|
|
203
232
|
CGAffineTransformMakeTranslation(0, 0.08 * transitionContext.containerView.bounds.size.height);
|
|
204
233
|
|
|
234
|
+
const float transitionDuration = [self transitionDuration:transitionContext];
|
|
235
|
+
|
|
205
236
|
if (_operation == UINavigationControllerOperationPush) {
|
|
206
237
|
toViewController.view.transform = topBottomTransform;
|
|
207
238
|
toViewController.view.alpha = 0.0;
|
|
@@ -209,7 +240,7 @@
|
|
|
209
240
|
|
|
210
241
|
// Android Nougat open animation
|
|
211
242
|
// http://aosp.opersys.com/xref/android-7.1.2_r37/xref/frameworks/base/core/res/res/anim/activity_open_enter.xml
|
|
212
|
-
[UIView animateWithDuration:0.35
|
|
243
|
+
[UIView animateWithDuration:transitionDuration * RNSSlideOpenTransitionDurationProportion // defaults to 0.35 s
|
|
213
244
|
delay:0
|
|
214
245
|
options:UIViewAnimationOptionCurveEaseOut
|
|
215
246
|
animations:^{
|
|
@@ -220,7 +251,7 @@
|
|
|
220
251
|
fromViewController.view.transform = CGAffineTransformIdentity;
|
|
221
252
|
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
|
|
222
253
|
}];
|
|
223
|
-
[UIView animateWithDuration:0.2
|
|
254
|
+
[UIView animateWithDuration:transitionDuration * RNSFadeOpenTransitionDurationProportion // defaults to 0.2 s
|
|
224
255
|
delay:0
|
|
225
256
|
options:UIViewAnimationOptionCurveEaseOut
|
|
226
257
|
animations:^{
|
|
@@ -234,7 +265,7 @@
|
|
|
234
265
|
|
|
235
266
|
// Android Nougat exit animation
|
|
236
267
|
// http://aosp.opersys.com/xref/android-7.1.2_r37/xref/frameworks/base/core/res/res/anim/activity_close_exit.xml
|
|
237
|
-
[UIView animateWithDuration:0.25
|
|
268
|
+
[UIView animateWithDuration:transitionDuration * RNSSlideCloseTransitionDurationProportion // defaults to 0.25 s
|
|
238
269
|
delay:0
|
|
239
270
|
options:UIViewAnimationOptionCurveEaseIn
|
|
240
271
|
animations:^{
|
|
@@ -244,8 +275,8 @@
|
|
|
244
275
|
completion:^(BOOL finished) {
|
|
245
276
|
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
|
|
246
277
|
}];
|
|
247
|
-
[UIView animateWithDuration:0.15
|
|
248
|
-
delay:0.1
|
|
278
|
+
[UIView animateWithDuration:transitionDuration * RNSFadeCloseTransitionDurationProportion // defaults to 0.15 s
|
|
279
|
+
delay:transitionDuration * RNSFadeCloseDelayTransitionDurationProportion // defaults to 0.1 s
|
|
249
280
|
options:UIViewAnimationOptionCurveLinear
|
|
250
281
|
animations:^{
|
|
251
282
|
fromViewController.view.alpha = 0.0;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
|
|
3
|
+
#import <React/RCTViewComponentView.h>
|
|
4
|
+
|
|
5
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
6
|
+
|
|
7
|
+
@interface RNSScreenStackComponentView : RCTViewComponentView
|
|
8
|
+
|
|
9
|
+
@end
|
|
10
|
+
|
|
11
|
+
@interface RNSScreenStackView : UIView
|
|
12
|
+
- (instancetype)initWithComponentView:(RNSScreenStackComponentView *)component;
|
|
13
|
+
@end
|
|
14
|
+
|
|
15
|
+
NS_ASSUME_NONNULL_END
|