iOS: 2/5 Remove use of bridge from Modal by dismissing with visible prop

Summary: Changelog: [Fabric][iOS][Fix] Remove use of bridge from Modal by dismissing Modal with visible prop

Reviewed By: sammy-SC

Differential Revision: D28074326

fbshipit-source-id: 0278bfb031db802b59429c553ac62d83838f4cc9
This commit is contained in:
Paige Sun
2021-05-02 15:42:49 -07:00
committed by Facebook GitHub Bot
parent 3c17922c35
commit 0932a0d775
9 changed files with 68 additions and 48 deletions
+7
View File
@@ -193,6 +193,7 @@ class Modal extends React.Component<Props> {
}
componentDidMount() {
// 'modalDismissed' is for the old renderer in iOS only
if (ModalEventEmitter) {
this._eventSubscription = ModalEventEmitter.addListener(
'modalDismissed',
@@ -251,6 +252,12 @@ class Modal extends React.Component<Props> {
hardwareAccelerated={this.props.hardwareAccelerated}
onRequestClose={this.props.onRequestClose}
onShow={this.props.onShow}
onDismiss={() => {
if (this.props.onDismiss) {
this.props.onDismiss();
}
}}
visible={this.props.visible}
statusBarTranslucent={this.props.statusBarTranslucent}
identifier={this._identifier}
style={styles.modal}
@@ -92,6 +92,13 @@ type NativeProps = $ReadOnly<{|
*/
onDismiss?: ?DirectEventHandler<null>,
/**
* The `visible` prop determines whether your modal is visible.
*
* See https://reactnative.dev/docs/modal.html#visible
*/
visible?: WithDefault<boolean, false>,
/**
* Deprecated. Use the `animationType` prop instead.
*/
@@ -14,6 +14,7 @@ exports[`<Modal /> should render as <RCTModalHostView> when not mocked 1`] = `
animationType="none"
hardwareAccelerated={false}
identifier={1}
onDismiss={[Function]}
onStartShouldSetResponder={[Function]}
presentationStyle="fullScreen"
style={
@@ -21,6 +22,7 @@ exports[`<Modal /> should render as <RCTModalHostView> when not mocked 1`] = `
"position": "absolute",
}
}
visible={true}
>
<View
collapsable={false}
@@ -25,11 +25,8 @@
* Subclasses may override this method.
* Default implementation calls `[UIViewController dismissViewControllerAnimated:completion:]`.
*/
- (void)dismissViewController:(UIViewController *)modalViewController animated:(BOOL)animated;
/**
* Should be called by subclasses when ViewController is dismissed.
*/
- (void)didDismissViewController;
- (void)dismissViewController:(UIViewController *)modalViewController
animated:(BOOL)animated
completion:(void (^)(void))completion;
@end
@@ -102,6 +102,7 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
RCTFabricModalHostViewController *_viewController;
ModalHostViewShadowNode::ConcreteState::Shared _state;
BOOL _shouldAnimatePresentation;
BOOL _shouldPresent;
BOOL _isPresented;
UIView *_modalContentsSnapshot;
}
@@ -137,49 +138,62 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
[controller presentViewController:modalViewController animated:animated completion:completion];
}
- (void)dismissViewController:(UIViewController *)modalViewController animated:(BOOL)animated
- (void)dismissViewController:(UIViewController *)modalViewController
animated:(BOOL)animated
completion:(void (^)(void))completion
{
[modalViewController dismissViewControllerAnimated:animated
completion:^{
[self didDismissViewController];
}];
}
- (void)didDismissViewController
{
const auto &props = *std::static_pointer_cast<ModalHostViewProps const>(_props);
[[RCTBridge currentBridge].modalManager modalDismissed:@(props.identifier)];
[modalViewController dismissViewControllerAnimated:animated completion:completion];
}
- (void)ensurePresentedOnlyIfNeeded
{
BOOL shouldBePresented = !_isPresented && self.window;
BOOL shouldBePresented = !_isPresented && _shouldPresent && self.window;
if (shouldBePresented) {
_isPresented = YES;
[self presentViewController:self.viewController
animated:_shouldAnimatePresentation
completion:^{
if (!self->_eventEmitter) {
return;
}
auto eventEmitter = [self modalEventEmitter];
if (eventEmitter) {
eventEmitter->onShow(ModalHostViewEventEmitter::OnShow{});
assert(std::dynamic_pointer_cast<ModalHostViewEventEmitter const>(self->_eventEmitter));
auto eventEmitter =
std::static_pointer_cast<ModalHostViewEventEmitter const>(self->_eventEmitter);
eventEmitter->onShow(ModalHostViewEventEmitter::OnShow{});
// A hack so that EventEmitter.cpp's eventTarget_ does not become null when modal is dismissed
eventEmitter->setEnabled(true);
}
}];
}
BOOL shouldBeHidden = _isPresented && !self.superview;
BOOL shouldBeHidden = _isPresented && (!_shouldPresent || !self.superview);
if (shouldBeHidden) {
_isPresented = NO;
// To animate dismissal of view controller, snapshot of
// view hierarchy needs to be added to the UIViewController.
[self.viewController.view addSubview:_modalContentsSnapshot];
[self dismissViewController:self.viewController animated:_shouldAnimatePresentation];
UIView *snapshot = _modalContentsSnapshot;
[self.viewController.view addSubview:snapshot];
auto eventEmitter = [self modalEventEmitter];
[self dismissViewController:self.viewController
animated:_shouldAnimatePresentation
completion:^{
[snapshot removeFromSuperview];
if (eventEmitter) {
eventEmitter->onDismiss(ModalHostViewEventEmitter::OnDismiss{});
}
}];
}
}
- (std::shared_ptr<const ModalHostViewEventEmitter>)modalEventEmitter
{
if (!self->_eventEmitter) {
return nullptr;
}
assert(std::dynamic_pointer_cast<ModalHostViewEventEmitter const>(self->_eventEmitter));
return std::static_pointer_cast<ModalHostViewEventEmitter const>(self->_eventEmitter);
}
#pragma mark - RCTMountingTransactionObserving
- (void)mountingTransactionWillMountWithMetadata:(MountingTransactionMetadata const &)metadata
@@ -205,10 +219,8 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
- (void)boundsDidChange:(CGRect)newBounds
{
if (_eventEmitter) {
assert(std::dynamic_pointer_cast<ModalHostViewEventEmitter const>(_eventEmitter));
auto eventEmitter = std::static_pointer_cast<ModalHostViewEventEmitter const>(_eventEmitter);
auto eventEmitter = [self modalEventEmitter];
if (eventEmitter) {
eventEmitter->onOrientationChange(onOrientationChangeStruct(newBounds));
}
@@ -231,6 +243,7 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
_state.reset();
_viewController = nil;
_isPresented = NO;
_shouldPresent = NO;
}
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
@@ -247,6 +260,9 @@ static ModalHostViewEventEmitter::OnOrientationChange onOrientationChangeStruct(
self.viewController.modalPresentationStyle = presentationConfiguration(newProps);
_shouldPresent = newProps.visible;
[self ensurePresentedOnlyIfNeeded];
[super updateProps:props oldProps:oldProps];
}
+1
View File
@@ -122,6 +122,7 @@ RCT_EXPORT_VIEW_PROPERTY(supportedOrientations, NSArray)
RCT_EXPORT_VIEW_PROPERTY(onOrientationChange, RCTDirectEventBlock)
// Fabric only
RCT_EXPORT_VIEW_PROPERTY(visible, BOOL)
RCT_EXPORT_VIEW_PROPERTY(onDismiss, RCTDirectEventBlock)
@end
-7
View File
@@ -7,7 +7,6 @@
#import <UIKit/UIKit.h>
#import <React/RCTBridge.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
@@ -16,9 +15,3 @@
- (void)modalDismissed:(NSNumber *)modalID;
@end
@interface RCTBridge (RCTModalManager)
@property (nonatomic, readonly) RCTModalManager *modalManager;
@end
-9
View File
@@ -40,12 +40,3 @@ RCT_EXPORT_MODULE();
}
@end
@implementation RCTBridge (RCTDevSettings)
- (RCTModalManager *)modalManager
{
return [self moduleForClass:[RCTModalManager class]];
}
@end
@@ -91,6 +91,12 @@ public class ReactModalHostManager extends ViewGroupManager<ReactModalHostView>
view.setHardwareAccelerated(hardwareAccelerated);
}
@Override
@ReactProp(name = "visible")
public void setVisible(ReactModalHostView view, boolean visible) {
// iOS only
}
@Override
public void setPresentationStyle(ReactModalHostView view, @Nullable String value) {}