From 17a1a8042d139614b2b03122919892a39e6a9199 Mon Sep 17 00:00:00 2001 From: Jorge Bernal Date: Thu, 26 Dec 2019 13:20:05 +0100 Subject: [PATCH] Implement onRequestClose for iOS 13+ modals --- Libraries/Modal/Modal.js | 3 ++- .../Modal/RCTModalHostViewNativeComponent.js | 3 ++- .../Modal/RCTModalHostViewComponentView.mm | 1 + React/Views/RCTModalHostView.h | 3 ++- React/Views/RCTModalHostView.m | 16 +++++++++++++++- React/Views/RCTModalHostViewManager.m | 3 --- 6 files changed, 22 insertions(+), 7 deletions(-) diff --git a/Libraries/Modal/Modal.js b/Libraries/Modal/Modal.js index 8cc55ffe5727..3a4f6d153587 100644 --- a/Libraries/Modal/Modal.js +++ b/Libraries/Modal/Modal.js @@ -95,7 +95,8 @@ export type Props = $ReadOnly<{| /** * The `onRequestClose` callback is called when the user taps the hardware - * back button on Android or the menu button on Apple TV. + * back button on Android, the menu button on Apple TV, or a modal is dismissed + * with a gesture on iOS 13+. * * This is required on Apple TV and Android. * diff --git a/Libraries/Modal/RCTModalHostViewNativeComponent.js b/Libraries/Modal/RCTModalHostViewNativeComponent.js index 9363a3b98d3c..43428715b846 100644 --- a/Libraries/Modal/RCTModalHostViewNativeComponent.js +++ b/Libraries/Modal/RCTModalHostViewNativeComponent.js @@ -70,7 +70,8 @@ type NativeProps = $ReadOnly<{| /** * The `onRequestClose` callback is called when the user taps the hardware - * back button on Android or the menu button on Apple TV. + * back button on Android, the menu button on Apple TV, or a modal is dismissed + * with a gesture on iOS 13+. * * This is required on Apple TV and Android. * diff --git a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm index cb6f3039a590..2731d0ea9a02 100644 --- a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm @@ -111,6 +111,7 @@ - (instancetype)initWithFrame:(CGRect)frame _viewController = [RCTFabricModalHostViewController new]; _viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; _viewController.delegate = self; + _viewController.presentationController.delegate = self; } return self; diff --git a/React/Views/RCTModalHostView.h b/React/Views/RCTModalHostView.h index e16dd222b50f..6a35fb29565e 100644 --- a/React/Views/RCTModalHostView.h +++ b/React/Views/RCTModalHostView.h @@ -32,8 +32,9 @@ @property (nonatomic, copy) NSArray *supportedOrientations; @property (nonatomic, copy) RCTDirectEventBlock onOrientationChange; -#if TARGET_OS_TV @property (nonatomic, copy) RCTDirectEventBlock onRequestClose; + +#if TARGET_OS_TV @property (nonatomic, strong) RCTTVRemoteHandler *tvRemoteHandler; #endif diff --git a/React/Views/RCTModalHostView.m b/React/Views/RCTModalHostView.m index 95d572bf3eb3..9b767155def6 100644 --- a/React/Views/RCTModalHostView.m +++ b/React/Views/RCTModalHostView.m @@ -20,6 +20,10 @@ #import "RCTTVRemoteHandler.h" #endif +@interface RCTModalHostView () + +@end + @implementation RCTModalHostView { __weak RCTBridge *_bridge; @@ -46,6 +50,7 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge UIView *containerView = [UIView new]; containerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; _modalViewController.view = containerView; + _modalViewController.presentationController.delegate = self; _touchHandler = [[RCTTouchHandler alloc] initWithBridge:bridge]; #if TARGET_OS_TV _menuButtonGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(menuButtonPressed:)]; @@ -70,10 +75,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]; @@ -81,8 +88,8 @@ - (void)setOnRequestClose:(RCTDirectEventBlock)onRequestClose [_reactSubview removeGestureRecognizer:_menuButtonGestureRecognizer]; } } + #endif } -#endif - (void)notifyForBoundsChange:(CGRect)newBounds { @@ -257,4 +264,11 @@ - (UIInterfaceOrientationMask)supportedOrientationsMask } #endif +- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController +{ + if (_onRequestClose) { + _onRequestClose(nil); + } +} + @end diff --git a/React/Views/RCTModalHostViewManager.m b/React/Views/RCTModalHostViewManager.m index 44f9ac9d2dac..9c0d13c478f3 100644 --- a/React/Views/RCTModalHostViewManager.m +++ b/React/Views/RCTModalHostViewManager.m @@ -108,9 +108,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