react-native-screens 3.10.2 → 3.11.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 +9 -7
- package/android/build.gradle +1 -0
- package/android/src/main/java/com/swmansion/rnscreens/Screen.kt +28 -11
- 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/ScreenViewManager.kt +10 -0
- 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/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/createNativeStackNavigator/README.md +12 -0
- package/ios/RNSScreen.h +10 -0
- package/ios/RNSScreen.m +34 -0
- package/ios/RNSScreenContainer.m +5 -0
- package/ios/RNSScreenStack.m +22 -7
- package/ios/RNSScreenStackAnimator.m +45 -14
- package/ios/RNSScreenStackHeaderConfig.m +4 -1
- package/ios/RNSScreenWindowTraits.h +1 -0
- package/ios/RNSScreenWindowTraits.m +20 -0
- package/ios/UIViewController+RNScreens.m +10 -0
- package/lib/commonjs/native-stack/views/NativeStackView.js +33 -4
- package/lib/commonjs/native-stack/views/NativeStackView.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 +1 -1
- package/reanimated/package.json +6 -0
- package/src/native-stack/types.tsx +34 -0
- package/src/native-stack/views/NativeStackView.tsx +33 -4
- package/src/types.tsx +60 -5
|
@@ -65,7 +65,9 @@ class SearchBarManager : ViewGroupManager<SearchBarView>() {
|
|
|
65
65
|
|
|
66
66
|
@ReactProp(name = "placeholder")
|
|
67
67
|
fun setPlaceholder(view: SearchBarView, placeholder: String?) {
|
|
68
|
-
|
|
68
|
+
if (placeholder != null) {
|
|
69
|
+
view.placeholder = placeholder
|
|
70
|
+
}
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
@ReactProp(name = "textColor", customType = "Color")
|
|
@@ -73,6 +75,21 @@ class SearchBarManager : ViewGroupManager<SearchBarView>() {
|
|
|
73
75
|
view.textColor = color
|
|
74
76
|
}
|
|
75
77
|
|
|
78
|
+
@ReactProp(name = "headerIconColor", customType = "Color")
|
|
79
|
+
fun setHeaderIconColor(view: SearchBarView, color: Int?) {
|
|
80
|
+
view.headerIconColor = color
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@ReactProp(name = "hintTextColor", customType = "Color")
|
|
84
|
+
fun setHintTextColor(view: SearchBarView, color: Int?) {
|
|
85
|
+
view.hintTextColor = color
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
@ReactProp(name = "shouldShowHintSearchIcon")
|
|
89
|
+
fun setShouldShowHintSearchIcon(view: SearchBarView, shouldShowHintSearchIcon: Boolean?) {
|
|
90
|
+
view.shouldShowHintSearchIcon = shouldShowHintSearchIcon ?: true
|
|
91
|
+
}
|
|
92
|
+
|
|
76
93
|
override fun getExportedCustomDirectEventTypeConstants(): Map<String, Any>? {
|
|
77
94
|
return MapBuilder.builder<String, Any>()
|
|
78
95
|
.put("onChangeText", MapBuilder.of("registrationName", "onChangeText"))
|
|
@@ -15,9 +15,12 @@ class SearchBarView(reactContext: ReactContext?) : ReactViewGroup(reactContext)
|
|
|
15
15
|
var autoCapitalize: SearchBarAutoCapitalize = SearchBarAutoCapitalize.NONE
|
|
16
16
|
var textColor: Int? = null
|
|
17
17
|
var tintColor: Int? = null
|
|
18
|
-
var
|
|
18
|
+
var headerIconColor: Int? = null
|
|
19
|
+
var hintTextColor: Int? = null
|
|
20
|
+
var placeholder: String = ""
|
|
19
21
|
var shouldOverrideBackButton: Boolean = true
|
|
20
22
|
var autoFocus: Boolean = false
|
|
23
|
+
var shouldShowHintSearchIcon: Boolean = true
|
|
21
24
|
|
|
22
25
|
private var mSearchViewFormatter: SearchViewFormatter? = null
|
|
23
26
|
|
|
@@ -45,9 +48,11 @@ class SearchBarView(reactContext: ReactContext?) : ReactViewGroup(reactContext)
|
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
searchView.inputType = inputType.toAndroidInputType(autoCapitalize)
|
|
48
|
-
searchView.queryHint = placeholder
|
|
49
51
|
mSearchViewFormatter?.setTextColor(textColor)
|
|
50
52
|
mSearchViewFormatter?.setTintColor(tintColor)
|
|
53
|
+
mSearchViewFormatter?.setHeaderIconColor(headerIconColor)
|
|
54
|
+
mSearchViewFormatter?.setHintTextColor(hintTextColor)
|
|
55
|
+
mSearchViewFormatter?.setPlaceholder(placeholder, shouldShowHintSearchIcon)
|
|
51
56
|
searchView.overrideBackAction = shouldOverrideBackButton
|
|
52
57
|
}
|
|
53
58
|
}
|
|
@@ -3,6 +3,8 @@ package com.swmansion.rnscreens
|
|
|
3
3
|
import android.graphics.drawable.Drawable
|
|
4
4
|
import android.view.View
|
|
5
5
|
import android.widget.EditText
|
|
6
|
+
import android.widget.ImageView
|
|
7
|
+
import androidx.appcompat.R
|
|
6
8
|
import androidx.appcompat.widget.SearchView
|
|
7
9
|
|
|
8
10
|
class SearchViewFormatter(var searchView: SearchView) {
|
|
@@ -10,9 +12,13 @@ class SearchViewFormatter(var searchView: SearchView) {
|
|
|
10
12
|
private var mDefaultTintBackground: Drawable? = null
|
|
11
13
|
|
|
12
14
|
private val searchEditText
|
|
13
|
-
get() = searchView.findViewById<View>(
|
|
15
|
+
get() = searchView.findViewById<View>(R.id.search_src_text) as? EditText
|
|
14
16
|
private val searchTextPlate
|
|
15
|
-
get() = searchView.findViewById<View>(
|
|
17
|
+
get() = searchView.findViewById<View>(R.id.search_plate)
|
|
18
|
+
private val searchIcon
|
|
19
|
+
get() = searchView.findViewById<ImageView>(R.id.search_button)
|
|
20
|
+
private val searchCloseIcon
|
|
21
|
+
get() = searchView.findViewById<ImageView>(R.id.search_close_btn)
|
|
16
22
|
|
|
17
23
|
fun setTextColor(textColor: Int?) {
|
|
18
24
|
val currentDefaultTextColor = mDefaultTextColor
|
|
@@ -37,4 +43,25 @@ class SearchViewFormatter(var searchView: SearchView) {
|
|
|
37
43
|
searchTextPlate.background = currentDefaultTintColor
|
|
38
44
|
}
|
|
39
45
|
}
|
|
46
|
+
|
|
47
|
+
fun setHeaderIconColor(headerIconColor: Int?) {
|
|
48
|
+
headerIconColor?.let {
|
|
49
|
+
searchIcon.setColorFilter(it)
|
|
50
|
+
searchCloseIcon.setColorFilter(it)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
fun setHintTextColor(hintTextColor: Int?) {
|
|
55
|
+
hintTextColor?.let {
|
|
56
|
+
searchEditText?.setHintTextColor(it)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
fun setPlaceholder(placeholder: String, shouldShowHintSearchIcon: Boolean) {
|
|
61
|
+
if (shouldShowHintSearchIcon) {
|
|
62
|
+
searchView.queryHint = placeholder
|
|
63
|
+
} else {
|
|
64
|
+
searchEditText?.hint = placeholder
|
|
65
|
+
}
|
|
66
|
+
}
|
|
40
67
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
+
<alpha
|
|
4
|
+
android:interpolator="@android:interpolator/accelerate_decelerate"
|
|
5
|
+
android:fromAlpha="0"
|
|
6
|
+
android:toAlpha="1.0"
|
|
7
|
+
android:startOffset="100"
|
|
8
|
+
android:duration="100"/>
|
|
9
|
+
<scale
|
|
10
|
+
android:interpolator="@android:interpolator/accelerate_decelerate"
|
|
11
|
+
android:fromXScale="0.85"
|
|
12
|
+
android:toXScale="1"
|
|
13
|
+
android:fromYScale="0.85"
|
|
14
|
+
android:toYScale="1"
|
|
15
|
+
android:pivotX="50%"
|
|
16
|
+
android:pivotY="50%"
|
|
17
|
+
android:duration="200"/>
|
|
18
|
+
</set>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
+
<alpha
|
|
4
|
+
android:fromAlpha="1"
|
|
5
|
+
android:toAlpha="0.4"
|
|
6
|
+
android:startOffset="100"
|
|
7
|
+
android:duration="100"
|
|
8
|
+
android:interpolator="@android:interpolator/accelerate_decelerate" />
|
|
9
|
+
|
|
10
|
+
<scale
|
|
11
|
+
android:interpolator="@android:interpolator/accelerate_decelerate"
|
|
12
|
+
android:fromXScale="1"
|
|
13
|
+
android:toXScale="1.15"
|
|
14
|
+
android:fromYScale="1"
|
|
15
|
+
android:toYScale="1.15"
|
|
16
|
+
android:pivotX="50%"
|
|
17
|
+
android:pivotY="50%"
|
|
18
|
+
android:duration="200"/>
|
|
19
|
+
</set>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
android:shareInterpolator="false">
|
|
4
|
+
<alpha
|
|
5
|
+
android:fromAlpha="0.0"
|
|
6
|
+
android:toAlpha="1"
|
|
7
|
+
android:startOffset="50"
|
|
8
|
+
android:duration="100"/>
|
|
9
|
+
<scale
|
|
10
|
+
android:fromXScale="1.15"
|
|
11
|
+
android:toXScale="1"
|
|
12
|
+
android:fromYScale="1.15"
|
|
13
|
+
android:toYScale="1"
|
|
14
|
+
android:pivotX="50%"
|
|
15
|
+
android:pivotY="50%"
|
|
16
|
+
android:duration="200"/>
|
|
17
|
+
</set>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
|
3
|
+
android:shareInterpolator="false"
|
|
4
|
+
android:zAdjustment="top">
|
|
5
|
+
<alpha
|
|
6
|
+
android:fromAlpha="1"
|
|
7
|
+
android:toAlpha="0.0"
|
|
8
|
+
android:startOffset="50"
|
|
9
|
+
android:duration="100"/>
|
|
10
|
+
<scale
|
|
11
|
+
android:fromXScale="1"
|
|
12
|
+
android:toXScale="0.85"
|
|
13
|
+
android:fromYScale="1"
|
|
14
|
+
android:toYScale="0.85"
|
|
15
|
+
android:pivotX="50%"
|
|
16
|
+
android:pivotY="50%"
|
|
17
|
+
android:duration="200"/>
|
|
18
|
+
</set>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!--Duration taken from debugging source code-->
|
|
3
|
+
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
|
4
|
+
android:fromAlpha="0.0"
|
|
5
|
+
android:toAlpha="1.0"
|
|
6
|
+
android:duration="150"
|
|
7
|
+
/> <!--Remember to change duration in the corresponding xml when modifying it-->
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!--Duration taken from debugging source code-->
|
|
3
|
+
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
|
4
|
+
android:fromAlpha="1.0"
|
|
5
|
+
android:toAlpha="0.0"
|
|
6
|
+
android:duration="150"
|
|
7
|
+
/> <!--Remember to change duration in the corresponding xml when modifying it-->
|
|
@@ -464,6 +464,18 @@ Defaults to an empty string.
|
|
|
464
464
|
|
|
465
465
|
The search field text color.
|
|
466
466
|
|
|
467
|
+
#### `hintTextColor`
|
|
468
|
+
|
|
469
|
+
The search hint text color. (Android only)
|
|
470
|
+
|
|
471
|
+
#### `headerIconColor`
|
|
472
|
+
|
|
473
|
+
The search and close icon color shown in the header. (Android only)
|
|
474
|
+
|
|
475
|
+
#### `shouldShowHintSearchIcon`
|
|
476
|
+
|
|
477
|
+
Show the search hint icon when search bar is focused. (Android only)
|
|
478
|
+
|
|
467
479
|
### Helpers
|
|
468
480
|
|
|
469
481
|
The stack navigator adds the following methods to the navigation prop:
|
package/ios/RNSScreen.h
CHANGED
|
@@ -29,6 +29,11 @@ typedef NS_ENUM(NSInteger, RNSScreenReplaceAnimation) {
|
|
|
29
29
|
RNSScreenReplaceAnimationPush,
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
+
typedef NS_ENUM(NSInteger, RNSScreenSwipeDirection) {
|
|
33
|
+
RNSScreenSwipeDirectionVertical,
|
|
34
|
+
RNSScreenSwipeDirectionHorizontal,
|
|
35
|
+
};
|
|
36
|
+
|
|
32
37
|
typedef NS_ENUM(NSInteger, RNSActivityState) {
|
|
33
38
|
RNSActivityStateInactive = 0,
|
|
34
39
|
RNSActivityStateTransitioningOrBelowTop = 1,
|
|
@@ -47,6 +52,7 @@ typedef NS_ENUM(NSInteger, RNSWindowTrait) {
|
|
|
47
52
|
RNSWindowTraitAnimation,
|
|
48
53
|
RNSWindowTraitHidden,
|
|
49
54
|
RNSWindowTraitOrientation,
|
|
55
|
+
RNSWindowTraitHomeIndicatorHidden,
|
|
50
56
|
};
|
|
51
57
|
|
|
52
58
|
@interface RCTConvert (RNSScreen)
|
|
@@ -91,19 +97,23 @@ typedef NS_ENUM(NSInteger, RNSWindowTrait) {
|
|
|
91
97
|
@property (nonatomic) RNSScreenStackAnimation stackAnimation;
|
|
92
98
|
@property (nonatomic) RNSScreenStackPresentation stackPresentation;
|
|
93
99
|
@property (nonatomic) RNSScreenReplaceAnimation replaceAnimation;
|
|
100
|
+
@property (nonatomic) RNSScreenSwipeDirection swipeDirection;
|
|
94
101
|
@property (nonatomic) BOOL preventNativeDismiss;
|
|
95
102
|
@property (nonatomic) BOOL hasOrientationSet;
|
|
96
103
|
@property (nonatomic) BOOL hasStatusBarStyleSet;
|
|
97
104
|
@property (nonatomic) BOOL hasStatusBarAnimationSet;
|
|
98
105
|
@property (nonatomic) BOOL hasStatusBarHiddenSet;
|
|
106
|
+
@property (nonatomic) BOOL hasHomeIndicatorHiddenSet;
|
|
99
107
|
@property (nonatomic) BOOL customAnimationOnSwipe;
|
|
100
108
|
@property (nonatomic) BOOL fullScreenSwipeEnabled;
|
|
109
|
+
@property (nonatomic, retain) NSNumber *transitionDuration;
|
|
101
110
|
|
|
102
111
|
#if !TARGET_OS_TV
|
|
103
112
|
@property (nonatomic) RNSStatusBarStyle statusBarStyle;
|
|
104
113
|
@property (nonatomic) UIStatusBarAnimation statusBarAnimation;
|
|
105
114
|
@property (nonatomic) BOOL statusBarHidden;
|
|
106
115
|
@property (nonatomic) UIInterfaceOrientationMask screenOrientation;
|
|
116
|
+
@property (nonatomic) BOOL homeIndicatorHidden;
|
|
107
117
|
#endif
|
|
108
118
|
|
|
109
119
|
- (void)notifyFinishTransitioning;
|
package/ios/RNSScreen.m
CHANGED
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
_hasStatusBarAnimationSet = NO;
|
|
35
35
|
_hasStatusBarHiddenSet = NO;
|
|
36
36
|
_hasOrientationSet = NO;
|
|
37
|
+
_hasHomeIndicatorHiddenSet = NO;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
return self;
|
|
@@ -206,6 +207,13 @@
|
|
|
206
207
|
_screenOrientation = screenOrientation;
|
|
207
208
|
[RNSScreenWindowTraits enforceDesiredDeviceOrientation];
|
|
208
209
|
}
|
|
210
|
+
|
|
211
|
+
- (void)setHomeIndicatorHidden:(BOOL)homeIndicatorHidden
|
|
212
|
+
{
|
|
213
|
+
_hasHomeIndicatorHiddenSet = YES;
|
|
214
|
+
_homeIndicatorHidden = homeIndicatorHidden;
|
|
215
|
+
[RNSScreenWindowTraits updateHomeIndicatorAutoHidden];
|
|
216
|
+
}
|
|
209
217
|
#endif
|
|
210
218
|
|
|
211
219
|
- (UIView *)reactSuperview
|
|
@@ -436,6 +444,17 @@
|
|
|
436
444
|
return UIInterfaceOrientationMaskAllButUpsideDown;
|
|
437
445
|
}
|
|
438
446
|
|
|
447
|
+
- (UIViewController *)childViewControllerForHomeIndicatorAutoHidden
|
|
448
|
+
{
|
|
449
|
+
UIViewController *vc = [self findChildVCForConfigAndTrait:RNSWindowTraitHomeIndicatorHidden includingModals:YES];
|
|
450
|
+
return vc == self ? nil : vc;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
- (BOOL)prefersHomeIndicatorAutoHidden
|
|
454
|
+
{
|
|
455
|
+
return ((RNSScreenView *)self.view).homeIndicatorHidden;
|
|
456
|
+
}
|
|
457
|
+
|
|
439
458
|
// if the returned vc is a child, it means that it can provide config;
|
|
440
459
|
// if the returned vc is self, it means that there is no child for config and self has config to provide,
|
|
441
460
|
// so we return self which results in asking self for preferredStatusBarStyle/Animation etc.;
|
|
@@ -495,6 +514,9 @@
|
|
|
495
514
|
case RNSWindowTraitOrientation: {
|
|
496
515
|
return ((RNSScreenView *)self.view).hasOrientationSet;
|
|
497
516
|
}
|
|
517
|
+
case RNSWindowTraitHomeIndicatorHidden: {
|
|
518
|
+
return ((RNSScreenView *)self.view).hasHomeIndicatorHiddenSet;
|
|
519
|
+
}
|
|
498
520
|
default: {
|
|
499
521
|
RCTLogError(@"Unknown trait passed: %d", (int)trait);
|
|
500
522
|
}
|
|
@@ -771,6 +793,8 @@ RCT_EXPORT_VIEW_PROPERTY(preventNativeDismiss, BOOL)
|
|
|
771
793
|
RCT_EXPORT_VIEW_PROPERTY(replaceAnimation, RNSScreenReplaceAnimation)
|
|
772
794
|
RCT_EXPORT_VIEW_PROPERTY(stackPresentation, RNSScreenStackPresentation)
|
|
773
795
|
RCT_EXPORT_VIEW_PROPERTY(stackAnimation, RNSScreenStackAnimation)
|
|
796
|
+
RCT_EXPORT_VIEW_PROPERTY(swipeDirection, RNSScreenSwipeDirection)
|
|
797
|
+
RCT_EXPORT_VIEW_PROPERTY(transitionDuration, NSNumber)
|
|
774
798
|
|
|
775
799
|
RCT_EXPORT_VIEW_PROPERTY(onAppear, RCTDirectEventBlock);
|
|
776
800
|
RCT_EXPORT_VIEW_PROPERTY(onDisappear, RCTDirectEventBlock);
|
|
@@ -785,6 +809,7 @@ RCT_EXPORT_VIEW_PROPERTY(screenOrientation, UIInterfaceOrientationMask)
|
|
|
785
809
|
RCT_EXPORT_VIEW_PROPERTY(statusBarAnimation, UIStatusBarAnimation)
|
|
786
810
|
RCT_EXPORT_VIEW_PROPERTY(statusBarHidden, BOOL)
|
|
787
811
|
RCT_EXPORT_VIEW_PROPERTY(statusBarStyle, RNSStatusBarStyle)
|
|
812
|
+
RCT_EXPORT_VIEW_PROPERTY(homeIndicatorHidden, BOOL)
|
|
788
813
|
#endif
|
|
789
814
|
|
|
790
815
|
- (UIView *)view
|
|
@@ -835,6 +860,15 @@ RCT_ENUM_CONVERTER(
|
|
|
835
860
|
RNSScreenReplaceAnimationPop,
|
|
836
861
|
integerValue)
|
|
837
862
|
|
|
863
|
+
RCT_ENUM_CONVERTER(
|
|
864
|
+
RNSScreenSwipeDirection,
|
|
865
|
+
(@{
|
|
866
|
+
@"vertical" : @(RNSScreenSwipeDirectionVertical),
|
|
867
|
+
@"horizontal" : @(RNSScreenSwipeDirectionHorizontal),
|
|
868
|
+
}),
|
|
869
|
+
RNSScreenSwipeDirectionHorizontal,
|
|
870
|
+
integerValue)
|
|
871
|
+
|
|
838
872
|
#if !TARGET_OS_TV
|
|
839
873
|
RCT_ENUM_CONVERTER(
|
|
840
874
|
RNSStatusBarStyle,
|
package/ios/RNSScreenContainer.m
CHANGED
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;
|
|
@@ -152,9 +152,12 @@
|
|
|
152
152
|
nextVC = nav.topViewController;
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
// we want updates sent to the VC below modal too since it is also visible
|
|
156
|
+
BOOL isPresentingVC = vc.presentedViewController == nextVC;
|
|
157
|
+
|
|
155
158
|
BOOL isInFullScreenModal = nav == nil && _screenView.stackPresentation == RNSScreenStackPresentationFullScreenModal;
|
|
156
159
|
// if nav is nil, it means we can be in a fullScreen modal, so there is no nextVC, but we still want to update
|
|
157
|
-
if (vc != nil && (nextVC == vc || isInFullScreenModal)) {
|
|
160
|
+
if (vc != nil && (nextVC == vc || isInFullScreenModal || isPresentingVC)) {
|
|
158
161
|
[RNSScreenStackHeaderConfig updateViewController:self.screenView.controller withConfig:self animated:YES];
|
|
159
162
|
}
|
|
160
163
|
}
|
|
@@ -42,6 +42,25 @@
|
|
|
42
42
|
#endif
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
+ (void)updateHomeIndicatorAutoHidden
|
|
46
|
+
{
|
|
47
|
+
#if !TARGET_OS_TV
|
|
48
|
+
|
|
49
|
+
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && defined(__IPHONE_13_0) && \
|
|
50
|
+
__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0
|
|
51
|
+
if (@available(iOS 13, *)) {
|
|
52
|
+
UIWindow *firstWindow = [[[UIApplication sharedApplication] windows] firstObject];
|
|
53
|
+
if (firstWindow != nil) {
|
|
54
|
+
[[firstWindow rootViewController] setNeedsUpdateOfHomeIndicatorAutoHidden];
|
|
55
|
+
}
|
|
56
|
+
} else
|
|
57
|
+
#endif
|
|
58
|
+
{
|
|
59
|
+
[UIApplication.sharedApplication.keyWindow.rootViewController setNeedsUpdateOfHomeIndicatorAutoHidden];
|
|
60
|
+
}
|
|
61
|
+
#endif
|
|
62
|
+
}
|
|
63
|
+
|
|
45
64
|
#if !TARGET_OS_TV
|
|
46
65
|
+ (UIStatusBarStyle)statusBarStyleForRNSStatusBarStyle:(RNSStatusBarStyle)statusBarStyle
|
|
47
66
|
{
|
|
@@ -165,6 +184,7 @@
|
|
|
165
184
|
{
|
|
166
185
|
[RNSScreenWindowTraits updateStatusBarAppearance];
|
|
167
186
|
[RNSScreenWindowTraits enforceDesiredDeviceOrientation];
|
|
187
|
+
[RNSScreenWindowTraits updateHomeIndicatorAutoHidden];
|
|
168
188
|
}
|
|
169
189
|
|
|
170
190
|
#if !TARGET_OS_TV
|
|
@@ -31,6 +31,12 @@
|
|
|
31
31
|
return childVC ? childVC.supportedInterfaceOrientations : [self reactNativeScreensSupportedInterfaceOrientations];
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
- (UIViewController *)reactNativeScreensChildViewControllerForHomeIndicatorAutoHidden
|
|
35
|
+
{
|
|
36
|
+
UIViewController *childVC = [self findChildRNScreensViewController];
|
|
37
|
+
return childVC ?: [self reactNativeScreensChildViewControllerForHomeIndicatorAutoHidden];
|
|
38
|
+
}
|
|
39
|
+
|
|
34
40
|
- (UIViewController *)findChildRNScreensViewController
|
|
35
41
|
{
|
|
36
42
|
UIViewController *lastViewController = [[self childViewControllers] lastObject];
|
|
@@ -61,6 +67,10 @@
|
|
|
61
67
|
method_exchangeImplementations(
|
|
62
68
|
class_getInstanceMethod(uiVCClass, @selector(supportedInterfaceOrientations)),
|
|
63
69
|
class_getInstanceMethod(uiVCClass, @selector(reactNativeScreensSupportedInterfaceOrientations)));
|
|
70
|
+
|
|
71
|
+
method_exchangeImplementations(
|
|
72
|
+
class_getInstanceMethod(uiVCClass, @selector(childViewControllerForHomeIndicatorAutoHidden)),
|
|
73
|
+
class_getInstanceMethod(uiVCClass, @selector(reactNativeScreensChildViewControllerForHomeIndicatorAutoHidden)));
|
|
64
74
|
});
|
|
65
75
|
}
|
|
66
76
|
#endif
|