diff --git a/Libraries/Modal/Modal.js b/Libraries/Modal/Modal.js index 8cc55ffe572..3a4f6d15358 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 9363a3b98d3..43428715b84 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 7fcbd62147f..574325af9fe 100644 --- a/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.mm @@ -94,7 +94,9 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct( return {orientation}; } -@interface RCTModalHostViewComponentView () +@interface RCTModalHostViewComponentView () < + RCTFabricModalHostViewControllerDelegate, + UIAdaptivePresentationControllerDelegate> @end @@ -113,6 +115,7 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct( _viewController = [RCTFabricModalHostViewController new]; _viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; _viewController.delegate = self; + _viewController.presentationController.delegate = self; } return self; @@ -217,6 +220,19 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct( [childComponentView removeFromSuperview]; } +#pragma mark - UIAdaptivePresentationControllerDelegate + +- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController +{ + if (!_eventEmitter) { + return; + } + + assert(std::dynamic_pointer_cast(_eventEmitter)); + auto eventEmitter = std::static_pointer_cast(_eventEmitter); + eventEmitter->onRequestClose({}); +} + @end Class RCTModalHostViewCls(void) diff --git a/React/Views/RCTModalHostView.h b/React/Views/RCTModalHostView.h index e16dd222b50..6a35fb29565 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 95d572bf3eb..9b767155def 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 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder) 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 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder) _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 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder) [_reactSubview removeGestureRecognizer:_menuButtonGestureRecognizer]; } } + #endif } -#endif - (void)notifyForBoundsChange:(CGRect)newBounds { @@ -257,4 +264,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder) } #endif +- (void)presentationControllerDidDismiss:(UIPresentationController *)presentationController +{ + if (_onRequestClose) { + _onRequestClose(nil); + } +} + @end diff --git a/React/Views/RCTModalHostViewManager.m b/React/Views/RCTModalHostViewManager.m index 44f9ac9d2da..9c0d13c478f 100644 --- a/React/Views/RCTModalHostViewManager.m +++ b/React/Views/RCTModalHostViewManager.m @@ -108,9 +108,6 @@ RCT_EXPORT_VIEW_PROPERTY(onShow, RCTDirectEventBlock) 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