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
@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