mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
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:
committed by
Facebook GitHub Bot
parent
3c17922c35
commit
0932a0d775
@@ -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];
|
||||
}
|
||||
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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) {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user