Last active
July 21, 2021 18:42
-
-
Save ps73/012b8b97bb7866db4b2b4636a8396d98 to your computer and use it in GitHub Desktop.
React Native 0.63.3 iOS Modal Swipe Down Bugfix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/node_modules/react-native/React/Views/RCTModalHostView.h b/node_modules/react-native/React/Views/RCTModalHostView.h | |
index 4e61886..2b8b6c0 100644 | |
--- a/node_modules/react-native/React/Views/RCTModalHostView.h | |
+++ b/node_modules/react-native/React/Views/RCTModalHostView.h | |
@@ -17,7 +17,7 @@ | |
@protocol RCTModalHostViewInteractor; | |
-@interface RCTModalHostView : UIView <RCTInvalidating> | |
+@interface RCTModalHostView : UIView <RCTInvalidating, UIAdaptivePresentationControllerDelegate> | |
@property (nonatomic, copy) NSString *animationType; | |
@property (nonatomic, assign) UIModalPresentationStyle presentationStyle; | |
@@ -31,9 +31,9 @@ | |
@property (nonatomic, copy) NSArray<NSString *> *supportedOrientations; | |
@property (nonatomic, copy) RCTDirectEventBlock onOrientationChange; | |
+@property (nonatomic, copy) RCTDirectEventBlock onRequestClose; | |
#if TARGET_OS_TV | |
-@property (nonatomic, copy) RCTDirectEventBlock onRequestClose; | |
@property (nonatomic, strong) RCTTVRemoteHandler *tvRemoteHandler; | |
#endif | |
diff --git a/node_modules/react-native/React/Views/RCTModalHostView.m b/node_modules/react-native/React/Views/RCTModalHostView.m | |
index 6a15330..9ed68db 100644 | |
--- a/node_modules/react-native/React/Views/RCTModalHostView.m | |
+++ b/node_modules/react-native/React/Views/RCTModalHostView.m | |
@@ -41,6 +41,9 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge | |
if ((self = [super initWithFrame:CGRectZero])) { | |
_bridge = bridge; | |
_modalViewController = [RCTModalHostViewController new]; | |
+ if (@available(iOS 13.0, *)) { | |
+ _modalViewController.presentationController.delegate = self; | |
+ } | |
UIView *containerView = [UIView new]; | |
containerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; | |
_modalViewController.view = containerView; | |
@@ -62,6 +65,22 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge | |
return self; | |
} | |
+- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection | |
+{ | |
+ if (self.presentationStyle == UIModalPresentationFullScreen && self.isTransparent) { | |
+ return UIModalPresentationOverFullScreen; | |
+ } | |
+ return self.presentationStyle; | |
+} | |
+ | |
+- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller | |
+{ | |
+ if (self.presentationStyle == UIModalPresentationFullScreen && self.isTransparent) { | |
+ return UIModalPresentationOverFullScreen; | |
+ } | |
+ return self.presentationStyle; | |
+} | |
+ | |
#if TARGET_OS_TV | |
- (void)menuButtonPressed:(__unused UIGestureRecognizer *)gestureRecognizer | |
{ | |
@@ -69,10 +88,12 @@ - (void)menuButtonPressed:(__unused UIGestureRecognizer *)gestureRecognizer | |
_onRequestClose(nil); | |
} | |
} | |
+#endif | |
- (void)setOnRequestClose:(RCTDirectEventBlock)onRequestClose | |
{ | |
_onRequestClose = onRequestClose; | |
+ #if TARGET_OS_TV | |
if (_reactSubview) { | |
if (_onRequestClose && _menuButtonGestureRecognizer) { | |
[_reactSubview addGestureRecognizer:_menuButtonGestureRecognizer]; | |
@@ -80,8 +101,8 @@ - (void)setOnRequestClose:(RCTDirectEventBlock)onRequestClose | |
[_reactSubview removeGestureRecognizer:_menuButtonGestureRecognizer]; | |
} | |
} | |
+ #endif | |
} | |
-#endif | |
- (void)notifyForBoundsChange:(CGRect)newBounds | |
{ | |
@@ -155,6 +176,14 @@ - (void)didUpdateReactSubviews | |
// Do nothing, as subview (singular) is managed by `insertReactSubview:atIndex:` | |
} | |
+- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController | |
+{ | |
+ if (_onRequestClose) { | |
+ _onRequestClose(nil); | |
+ } | |
+} | |
+ | |
+ | |
- (void)dismissModalViewController | |
{ | |
if (_isPresented) { | |
@@ -187,6 +216,12 @@ - (void)didMoveToWindow | |
if (self.presentationStyle != UIModalPresentationNone) { | |
_modalViewController.modalPresentationStyle = self.presentationStyle; | |
} | |
+ // only handle swipe close when onRequest method is provided | |
+ if (@available(iOS 13.0, *)) { | |
+ if (_onRequestClose) { | |
+ _modalViewController.modalInPresentation = self.presentationStyle != UIModalPresentationFormSheet && self.presentationStyle != UIModalPresentationPageSheet; | |
+ } | |
+ } | |
[_delegate presentModalHostView:self withViewController:_modalViewController animated:[self hasAnimationType]]; | |
_isPresented = YES; | |
} | |
diff --git a/node_modules/react-native/React/Views/RCTModalHostViewManager.m b/node_modules/react-native/React/Views/RCTModalHostViewManager.m | |
index bafab9d..d56bb52 100644 | |
--- a/node_modules/react-native/React/Views/RCTModalHostViewManager.m | |
+++ b/node_modules/react-native/React/Views/RCTModalHostViewManager.m | |
@@ -116,9 +116,6 @@ - (void)invalidate | |
RCT_EXPORT_VIEW_PROPERTY(identifier, NSNumber) | |
RCT_EXPORT_VIEW_PROPERTY(supportedOrientations, NSArray) | |
RCT_EXPORT_VIEW_PROPERTY(onOrientationChange, RCTDirectEventBlock) | |
- | |
-#if TARGET_OS_TV | |
RCT_EXPORT_VIEW_PROPERTY(onRequestClose, RCTDirectEventBlock) | |
-#endif | |
@end | |
diff --git a/node_modules/react-native/scripts/.packager.env b/node_modules/react-native/scripts/.packager.env | |
new file mode 100644 | |
index 0000000..361f5fb | |
--- /dev/null | |
+++ b/node_modules/react-native/scripts/.packager.env | |
@@ -0,0 +1 @@ | |
+export RCT_METRO_PORT=8081 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/node_modules/react-native/React/Views/RCTModalHostView.h b/node_modules/react-native/React/Views/RCTModalHostView.h | |
index 4e61886..2b8b6c0 100644 | |
--- a/node_modules/react-native/React/Views/RCTModalHostView.h | |
+++ b/node_modules/react-native/React/Views/RCTModalHostView.h | |
@@ -17,7 +17,7 @@ | |
@protocol RCTModalHostViewInteractor; | |
-@interface RCTModalHostView : UIView <RCTInvalidating> | |
+@interface RCTModalHostView : UIView <RCTInvalidating, UIAdaptivePresentationControllerDelegate> | |
@property (nonatomic, copy) NSString *animationType; | |
@property (nonatomic, assign) UIModalPresentationStyle presentationStyle; | |
@@ -31,9 +31,9 @@ | |
@property (nonatomic, copy) NSArray<NSString *> *supportedOrientations; | |
@property (nonatomic, copy) RCTDirectEventBlock onOrientationChange; | |
+@property (nonatomic, copy) RCTDirectEventBlock onRequestClose; | |
#if TARGET_OS_TV | |
-@property (nonatomic, copy) RCTDirectEventBlock onRequestClose; | |
@property (nonatomic, strong) RCTTVRemoteHandler *tvRemoteHandler; | |
#endif | |
diff --git a/node_modules/react-native/React/Views/RCTModalHostView.m b/node_modules/react-native/React/Views/RCTModalHostView.m | |
index 6a15330..9ed68db 100644 | |
--- a/node_modules/react-native/React/Views/RCTModalHostView.m | |
+++ b/node_modules/react-native/React/Views/RCTModalHostView.m | |
@@ -41,6 +41,9 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge | |
if ((self = [super initWithFrame:CGRectZero])) { | |
_bridge = bridge; | |
_modalViewController = [RCTModalHostViewController new]; | |
+ if (@available(iOS 13.0, *)) { | |
+ _modalViewController.presentationController.delegate = self; | |
+ } | |
UIView *containerView = [UIView new]; | |
containerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; | |
_modalViewController.view = containerView; | |
@@ -62,6 +65,22 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge | |
return self; | |
} | |
+- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller traitCollection:(UITraitCollection *)traitCollection | |
+{ | |
+ if (self.presentationStyle == UIModalPresentationFullScreen && self.isTransparent) { | |
+ return UIModalPresentationOverFullScreen; | |
+ } | |
+ return self.presentationStyle; | |
+} | |
+ | |
+- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller | |
+{ | |
+ if (self.presentationStyle == UIModalPresentationFullScreen && self.isTransparent) { | |
+ return UIModalPresentationOverFullScreen; | |
+ } | |
+ return self.presentationStyle; | |
+} | |
+ | |
#if TARGET_OS_TV | |
- (void)menuButtonPressed:(__unused UIGestureRecognizer *)gestureRecognizer | |
{ | |
@@ -69,10 +88,12 @@ - (void)menuButtonPressed:(__unused UIGestureRecognizer *)gestureRecognizer | |
_onRequestClose(nil); | |
} | |
} | |
+#endif | |
- (void)setOnRequestClose:(RCTDirectEventBlock)onRequestClose | |
{ | |
_onRequestClose = onRequestClose; | |
+ #if TARGET_OS_TV | |
if (_reactSubview) { | |
if (_onRequestClose && _menuButtonGestureRecognizer) { | |
[_reactSubview addGestureRecognizer:_menuButtonGestureRecognizer]; | |
@@ -80,8 +101,8 @@ - (void)setOnRequestClose:(RCTDirectEventBlock)onRequestClose | |
[_reactSubview removeGestureRecognizer:_menuButtonGestureRecognizer]; | |
} | |
} | |
+ #endif | |
} | |
-#endif | |
- (void)notifyForBoundsChange:(CGRect)newBounds | |
{ | |
@@ -155,6 +176,14 @@ - (void)didUpdateReactSubviews | |
// Do nothing, as subview (singular) is managed by `insertReactSubview:atIndex:` | |
} | |
+- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController | |
+{ | |
+ if (_onRequestClose) { | |
+ _onRequestClose(nil); | |
+ } | |
+} | |
+ | |
+ | |
- (void)dismissModalViewController | |
{ | |
if (_isPresented) { | |
@@ -187,6 +216,12 @@ - (void)didMoveToWindow | |
if (self.presentationStyle != UIModalPresentationNone) { | |
_modalViewController.modalPresentationStyle = self.presentationStyle; | |
} | |
+ // only handle swipe close when onRequest method is provided | |
+ if (@available(iOS 13.0, *)) { | |
+ if (_onRequestClose) { | |
+ _modalViewController.modalInPresentation = self.presentationStyle != UIModalPresentationFormSheet && self.presentationStyle != UIModalPresentationPageSheet; | |
+ } | |
+ } | |
[_delegate presentModalHostView:self withViewController:_modalViewController animated:[self hasAnimationType]]; | |
_isPresented = YES; | |
} | |
diff --git a/node_modules/react-native/React/Views/RCTModalHostViewManager.m b/node_modules/react-native/React/Views/RCTModalHostViewManager.m | |
index bafab9d..d56bb52 100644 | |
--- a/node_modules/react-native/React/Views/RCTModalHostViewManager.m | |
+++ b/node_modules/react-native/React/Views/RCTModalHostViewManager.m | |
@@ -116,9 +116,6 @@ - (void)invalidate | |
RCT_EXPORT_VIEW_PROPERTY(identifier, NSNumber) | |
RCT_EXPORT_VIEW_PROPERTY(supportedOrientations, NSArray) | |
RCT_EXPORT_VIEW_PROPERTY(onOrientationChange, RCTDirectEventBlock) | |
- | |
-#if TARGET_OS_TV | |
RCT_EXPORT_VIEW_PROPERTY(onRequestClose, RCTDirectEventBlock) | |
-#endif | |
@end | |
diff --git a/node_modules/react-native/scripts/.packager.env b/node_modules/react-native/scripts/.packager.env | |
new file mode 100644 | |
index 0000000..361f5fb | |
--- /dev/null | |
+++ b/node_modules/react-native/scripts/.packager.env | |
@@ -0,0 +1 @@ | |
+export RCT_METRO_PORT=8081 |
yes i am using it, here is how
<RNModal
animationType="slide"
transparent={true}
visible={modalVisible}
hardwareAccelerated
presentationStyle={'pageSheet'}
onDismiss={() => {
console.log('test');
}}
onRequestClose={() => {
console.log('test');
}}
>
@panvourtsis It isn't a problem with this gist, your postinstall is not executed by default when you are using yarn (I use npm). To get this working with yarn you have to do additional adaptations. https://yarnpkg.com/package/postinstall
Also you have to set modalVisible
to false in your onRequestClose
method
@ps73 thanks for all your help, i didn everything correctly after all but for some reason on iphone it wasn't working but after a new installation it work. Thanks for your work as well
Nice work, Thanks!
Wow! This works incredibly well. Thanks @ps73
What about 0.64.0?
What about 0.64.0?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@panvourtsis Do you use the
onRequestClose
property on the modal component? If this prop isn't set the swipe down is disabled as well as the Back Button on Android...