From 8933724d7d0f9ec012b2708d8e737f02f03e4a6f Mon Sep 17 00:00:00 2001 From: Mi-ZAZ <50288536+Mi-ZAZ@users.noreply.github.com> Date: Wed, 9 Sep 2020 06:38:48 -0700 Subject: [PATCH] Update RCTModalHostViewManager.m (#29745) Summary: Fix a issue that RCTModalHostView can't be dismissed while being presented Steps To Reproduce A native modal presented view controller is being dismissed before the first screen shows. A RCTModalHostView is presented when the first screen shows. The RCTModalHostView will be dismissed after an asynchronous callback. If the callback was called before the completion of the presenting animation, the RCTModalHostView will not be dismissed. ## Changelog [iOS] [Fixed] - Fix that RCTModalHostView can't be dismissed while being presented Pull Request resolved: https://github.com/facebook/react-native/pull/29745 Reviewed By: shergin Differential Revision: D23566487 Pulled By: sammy-SC fbshipit-source-id: bd95f200b79fa75e2387e402091d58c0f538759c --- React/Views/RCTModalHostViewManager.m | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/React/Views/RCTModalHostViewManager.m b/React/Views/RCTModalHostViewManager.m index bafab9dff9f3a9..4698139f90102b 100644 --- a/React/Views/RCTModalHostViewManager.m +++ b/React/Views/RCTModalHostViewManager.m @@ -48,6 +48,8 @@ - (void)insertReactSubview:(id)subview atIndex:(NSInteger)atIndex @interface RCTModalHostViewManager () +@property (nonatomic, copy) dispatch_block_t dismissWaitingBlock; + @end @implementation RCTModalHostViewManager { @@ -79,9 +81,16 @@ - (void)presentModalHostView:(RCTModalHostView *)modalHostView if (_presentationBlock) { _presentationBlock([modalHostView reactViewController], viewController, animated, completionBlock); } else { + __weak typeof(self) weakself = self; [[modalHostView reactViewController] presentViewController:viewController animated:animated - completion:completionBlock]; + completion:^{ + !completionBlock ?: completionBlock(); + __strong typeof(weakself) strongself = weakself; + !strongself.dismissWaitingBlock + ?: strongself.dismissWaitingBlock(); + strongself.dismissWaitingBlock = nil; + }]; } } @@ -92,7 +101,13 @@ - (void)dismissModalHostView:(RCTModalHostView *)modalHostView if (_dismissalBlock) { _dismissalBlock([modalHostView reactViewController], viewController, animated, nil); } else { - [viewController.presentingViewController dismissViewControllerAnimated:animated completion:nil]; + self.dismissWaitingBlock = ^{ + [viewController.presentingViewController dismissViewControllerAnimated:animated completion:nil]; + }; + if (viewController.presentingViewController) { + self.dismissWaitingBlock(); + self.dismissWaitingBlock = nil; + } } }