Skip to content

Instantly share code, notes, and snippets.

@ps73
Last active July 21, 2021 18:42
Show Gist options
  • Save ps73/012b8b97bb7866db4b2b4636a8396d98 to your computer and use it in GitHub Desktop.
Save ps73/012b8b97bb7866db4b2b4636a8396d98 to your computer and use it in GitHub Desktop.
React Native 0.63.3 iOS Modal Swipe Down Bugfix
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
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
@ps73
Copy link
Author

ps73 commented Dec 8, 2020

@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

@panvourtsis
Copy link

@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

@luokuning
Copy link

Nice work, Thanks!

@ericning00
Copy link

Wow! This works incredibly well. Thanks @ps73

@whalemare
Copy link

What about 0.64.0?

@sgup
Copy link

sgup commented Jul 21, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment