mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-04-29 04:45:19 +08:00
Compare commits
4 Commits
2.0.0-beta
...
2.0.0-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26d8dc21d2 | ||
|
|
3193e7da8f | ||
|
|
cce8373a20 | ||
|
|
823d11e691 |
@@ -23,6 +23,10 @@ public class ScreenFragment extends Fragment {
|
|||||||
((ViewGroup) parent).endViewTransition(view);
|
((ViewGroup) parent).endViewTransition(view);
|
||||||
((ViewGroup) parent).removeView(view);
|
((ViewGroup) parent).removeView(view);
|
||||||
}
|
}
|
||||||
|
// view detached from fragment manager get their visibility changed to GONE after their state is
|
||||||
|
// dumped. Since we don't restore the state but want to reuse the view we need to change visibility
|
||||||
|
// back to VISIBLE in order for the fragment manager to animate in the view.
|
||||||
|
view.setVisibility(View.VISIBLE);
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,11 +31,6 @@ public class ScreenStackFragment extends ScreenFragment {
|
|||||||
mFragment = fragment;
|
mFragment = fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startAnimation(Animation animation) {
|
|
||||||
super.startAnimation(animation);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onAnimationEnd() {
|
protected void onAnimationEnd() {
|
||||||
super.onAnimationEnd();
|
super.onAnimationEnd();
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class ScreenViewManager extends ViewGroupManager<Screen> {
|
|||||||
public void setStackPresentation(Screen view, String presentation) {
|
public void setStackPresentation(Screen view, String presentation) {
|
||||||
if ("push".equals(presentation)) {
|
if ("push".equals(presentation)) {
|
||||||
view.setStackPresentation(Screen.StackPresentation.PUSH);
|
view.setStackPresentation(Screen.StackPresentation.PUSH);
|
||||||
} else if ("modal".equals(presentation) || "containedModal".equals(presentation)) {
|
} else if ("modal".equals(presentation) || "containedModal".equals(presentation) || "fullScreenModal".equals(presentation) || "formSheet".equals(presentation)) {
|
||||||
// at the moment Android implementation does not handle contained vs regular modals
|
// at the moment Android implementation does not handle contained vs regular modals
|
||||||
view.setStackPresentation(Screen.StackPresentation.MODAL);
|
view.setStackPresentation(Screen.StackPresentation.MODAL);
|
||||||
} else if ("transparentModal".equals(presentation) || "containedTransparentModal".equals((presentation))) {
|
} else if ("transparentModal".equals(presentation) || "containedTransparentModal".equals((presentation))) {
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ typedef NS_ENUM(NSInteger, RNSScreenStackPresentation) {
|
|||||||
RNSScreenStackPresentationModal,
|
RNSScreenStackPresentationModal,
|
||||||
RNSScreenStackPresentationTransparentModal,
|
RNSScreenStackPresentationTransparentModal,
|
||||||
RNSScreenStackPresentationContainedModal,
|
RNSScreenStackPresentationContainedModal,
|
||||||
RNSScreenStackPresentationContainedTransparentModal
|
RNSScreenStackPresentationContainedTransparentModal,
|
||||||
|
RNSScreenStackPresentationFullScreenModal,
|
||||||
|
RNSScreenStackPresentationFormSheet
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef NS_ENUM(NSInteger, RNSScreenStackAnimation) {
|
typedef NS_ENUM(NSInteger, RNSScreenStackAnimation) {
|
||||||
|
|||||||
@@ -80,6 +80,12 @@
|
|||||||
_controller.modalPresentationStyle = UIModalPresentationFullScreen;
|
_controller.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
case RNSScreenStackPresentationFullScreenModal:
|
||||||
|
_controller.modalPresentationStyle = UIModalPresentationFullScreen;
|
||||||
|
break;
|
||||||
|
case RNSScreenStackPresentationFormSheet:
|
||||||
|
_controller.modalPresentationStyle = UIModalPresentationFormSheet;
|
||||||
|
break;
|
||||||
case RNSScreenStackPresentationTransparentModal:
|
case RNSScreenStackPresentationTransparentModal:
|
||||||
_controller.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
_controller.modalPresentationStyle = UIModalPresentationOverFullScreen;
|
||||||
break;
|
break;
|
||||||
@@ -315,6 +321,8 @@ RCT_EXPORT_VIEW_PROPERTY(onDismissed, RCTDirectEventBlock);
|
|||||||
RCT_ENUM_CONVERTER(RNSScreenStackPresentation, (@{
|
RCT_ENUM_CONVERTER(RNSScreenStackPresentation, (@{
|
||||||
@"push": @(RNSScreenStackPresentationPush),
|
@"push": @(RNSScreenStackPresentationPush),
|
||||||
@"modal": @(RNSScreenStackPresentationModal),
|
@"modal": @(RNSScreenStackPresentationModal),
|
||||||
|
@"fullScreenModal": @(RNSScreenStackPresentationFullScreenModal),
|
||||||
|
@"formSheet": @(RNSScreenStackPresentationFormSheet),
|
||||||
@"containedModal": @(RNSScreenStackPresentationContainedModal),
|
@"containedModal": @(RNSScreenStackPresentationContainedModal),
|
||||||
@"transparentModal": @(RNSScreenStackPresentationTransparentModal),
|
@"transparentModal": @(RNSScreenStackPresentationTransparentModal),
|
||||||
@"containedTransparentModal": @(RNSScreenStackPresentationContainedTransparentModal)
|
@"containedTransparentModal": @(RNSScreenStackPresentationContainedTransparentModal)
|
||||||
|
|||||||
@@ -10,6 +10,11 @@
|
|||||||
#import <React/RCTTouchHandler.h>
|
#import <React/RCTTouchHandler.h>
|
||||||
|
|
||||||
@interface RNSScreenStackView () <UINavigationControllerDelegate, UIAdaptivePresentationControllerDelegate, UIGestureRecognizerDelegate>
|
@interface RNSScreenStackView () <UINavigationControllerDelegate, UIAdaptivePresentationControllerDelegate, UIGestureRecognizerDelegate>
|
||||||
|
|
||||||
|
@property (nonatomic) NSMutableArray<UIViewController *> *presentedModals;
|
||||||
|
@property (nonatomic) BOOL updatingModals;
|
||||||
|
@property (nonatomic) BOOL scheduleModalsUpdate;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface RNSScreenStackAnimator : NSObject <UIViewControllerAnimatedTransitioning>
|
@interface RNSScreenStackAnimator : NSObject <UIViewControllerAnimatedTransitioning>
|
||||||
@@ -21,7 +26,6 @@
|
|||||||
UINavigationController *_controller;
|
UINavigationController *_controller;
|
||||||
NSMutableArray<RNSScreenView *> *_reactSubviews;
|
NSMutableArray<RNSScreenView *> *_reactSubviews;
|
||||||
NSMutableSet<RNSScreenView *> *_dismissedScreens;
|
NSMutableSet<RNSScreenView *> *_dismissedScreens;
|
||||||
NSMutableArray<UIViewController *> *_presentedModals;
|
|
||||||
__weak RNSScreenStackManager *_manager;
|
__weak RNSScreenStackManager *_manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,10 +164,20 @@
|
|||||||
|
|
||||||
- (void)didUpdateReactSubviews
|
- (void)didUpdateReactSubviews
|
||||||
{
|
{
|
||||||
// do nothing
|
|
||||||
[self updateContainer];
|
[self updateContainer];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)didMoveToWindow
|
||||||
|
{
|
||||||
|
[super didMoveToWindow];
|
||||||
|
if (self.window) {
|
||||||
|
// when stack is added to a window we try to update push and modal view controllers. It is
|
||||||
|
// because modal operations are blocked by UIKit when parent VC is not mounted, so we need
|
||||||
|
// to redo them when the stack is attached.
|
||||||
|
[self updateContainer];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void)setModalViewControllers:(NSArray<UIViewController *> *)controllers
|
- (void)setModalViewControllers:(NSArray<UIViewController *> *)controllers
|
||||||
{
|
{
|
||||||
// when there is no change we return immediately. This check is important because sometime we may
|
// when there is no change we return immediately. This check is important because sometime we may
|
||||||
@@ -197,26 +211,57 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prevent re-entry
|
||||||
|
if (_updatingModals) {
|
||||||
|
_scheduleModalsUpdate = YES;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_updatingModals = YES;
|
||||||
|
|
||||||
__weak RNSScreenStackView *weakSelf = self;
|
__weak RNSScreenStackView *weakSelf = self;
|
||||||
|
|
||||||
void (^dispatchFinishTransitioning)(void) = ^{
|
void (^afterTransitions)(void) = ^{
|
||||||
if (weakSelf.onFinishTransitioning) {
|
if (weakSelf.onFinishTransitioning) {
|
||||||
weakSelf.onFinishTransitioning(nil);
|
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];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void (^finish)(void) = ^{
|
void (^finish)(void) = ^{
|
||||||
UIViewController *previous = changeRootController;
|
NSUInteger oldCount = weakSelf.presentedModals.count;
|
||||||
for (NSUInteger i = changeRootIndex; i < controllers.count; i++) {
|
if (changeRootIndex < oldCount) {
|
||||||
UIViewController *next = controllers[i];
|
[weakSelf.presentedModals
|
||||||
BOOL animate = (i == controllers.count - 1);
|
removeObjectsInRange:NSMakeRange(changeRootIndex, oldCount - changeRootIndex)];
|
||||||
[previous presentViewController:next
|
|
||||||
animated:animate
|
|
||||||
completion:animate ? dispatchFinishTransitioning : nil];
|
|
||||||
previous = next;
|
|
||||||
}
|
}
|
||||||
if (changeRootIndex >= controllers.count) {
|
if (changeRootController.view.window == nil || changeRootIndex >= controllers.count) {
|
||||||
dispatchFinishTransitioning();
|
// 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);
|
||||||
|
[previous presentViewController:next
|
||||||
|
animated:lastModal
|
||||||
|
completion:^{
|
||||||
|
[weakSelf.presentedModals addObject:next];
|
||||||
|
if (lastModal) {
|
||||||
|
afterTransitions();
|
||||||
|
};
|
||||||
|
}];
|
||||||
|
previous = next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -227,7 +272,6 @@
|
|||||||
} else {
|
} else {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
[_presentedModals setArray:controllers];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setPushViewControllers:(NSArray<UIViewController *> *)controllers
|
- (void)setPushViewControllers:(NSArray<UIViewController *> *)controllers
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-native-screens",
|
"name": "react-native-screens",
|
||||||
"version": "2.0.0-beta.6",
|
"version": "2.0.0-beta.7",
|
||||||
"description": "First incomplete navigation solution for your react-native app.",
|
"description": "First incomplete navigation solution for your react-native app.",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node node_modules/react-native/local-cli/cli.js start",
|
"start": "node node_modules/react-native/local-cli/cli.js start",
|
||||||
|
|||||||
2
src/screens.d.ts
vendored
2
src/screens.d.ts
vendored
@@ -15,7 +15,7 @@ declare module 'react-native-screens' {
|
|||||||
export function enableScreens(shouldEnableScreens?: boolean): void;
|
export function enableScreens(shouldEnableScreens?: boolean): void;
|
||||||
export function screensEnabled(): boolean;
|
export function screensEnabled(): boolean;
|
||||||
|
|
||||||
export type StackPresentationTypes = 'push' | 'modal' | 'transparentModal';
|
export type StackPresentationTypes = 'push' | 'modal' | 'transparentModal' | 'fullScreenModal' | 'formSheet';
|
||||||
export type StackAnimationTypes = 'default' | 'fade' | 'flip' | 'none';
|
export type StackAnimationTypes = 'default' | 'fade' | 'flip' | 'none';
|
||||||
|
|
||||||
export interface ScreenProps extends ViewProps {
|
export interface ScreenProps extends ViewProps {
|
||||||
|
|||||||
Reference in New Issue
Block a user