Skip to content

Commit

Permalink
[iOS] [Fixed] - Revert [previous incomplete fix](facebook@bd2b7d6) fo…
Browse files Browse the repository at this point in the history
…r [an issue](facebook#26473) with `Modal`’s `onDismiss` prop.

This reverts commit bd2b7d6.
  • Loading branch information
grabbou authored and alloy committed Apr 3, 2020
1 parent 8ba46aa commit 27a3248
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 5 deletions.
28 changes: 25 additions & 3 deletions Libraries/Modal/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@

const AppContainer = require('../ReactNative/AppContainer');
const I18nManager = require('../ReactNative/I18nManager');
const PropTypes = require('prop-types');
const NativeEventEmitter = require('../EventEmitter/NativeEventEmitter');
import NativeModalManager from './NativeModalManager';
const Platform = require('../Utilities/Platform');
const React = require('react');
const PropTypes = require('prop-types');
const ScrollView = require('../Components/ScrollView/ScrollView');
const StyleSheet = require('../StyleSheet/StyleSheet');
const View = require('../Components/View/View');
Expand All @@ -22,6 +25,12 @@ import type {ViewProps} from '../Components/View/ViewPropTypes';
import type {DirectEventHandler} from '../Types/CodegenTypes';
import type EmitterSubscription from '../vendor/emitter/EmitterSubscription';
import RCTModalHostView from './RCTModalHostViewNativeComponent';

const ModalEventEmitter =
Platform.OS === 'ios' && NativeModalManager != null
? new NativeEventEmitter(NativeModalManager)
: null;

/**
* The Modal component is a simple way to present content above an enclosing view.
*
Expand Down Expand Up @@ -178,9 +187,22 @@ class Modal extends React.Component<Props> {
};
}

componentDidMount() {
if (ModalEventEmitter) {
this._eventSubscription = ModalEventEmitter.addListener(
'modalDismissed',
event => {
if (event.modalID === this._identifier && this.props.onDismiss) {
this.props.onDismiss();
}
},
);
}
}

componentWillUnmount() {
if (this.props.onDismiss != null) {
this.props.onDismiss();
if (this._eventSubscription) {
this._eventSubscription.remove();
}
}

Expand Down
8 changes: 8 additions & 0 deletions Libraries/Modal/RCTModalHostViewNativeComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ type NativeProps = $ReadOnly<{|
*/
onShow?: ?DirectEventHandler<null>,

/**
* The `onDismiss` prop allows passing a function that will be called once
* the modal has been dismissed.
*
* See https://facebook.github.io/react-native/docs/modal.html#ondismiss
*/
onDismiss?: ?BubblingEventHandler<null>,

/**
* Deprecated. Use the `animationType` prop instead.
*/
Expand Down
10 changes: 8 additions & 2 deletions React/Views/RCTModalHostViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import "RCTBridge.h"
#import "RCTModalHostView.h"
#import "RCTModalHostViewController.h"
#import "RCTModalManager.h"
#import "RCTShadowView.h"
#import "RCTUtils.h"

Expand Down Expand Up @@ -80,10 +81,15 @@ - (void)presentModalHostView:(RCTModalHostView *)modalHostView withViewControlle

- (void)dismissModalHostView:(RCTModalHostView *)modalHostView withViewController:(RCTModalHostViewController *)viewController animated:(BOOL)animated
{
dispatch_block_t completionBlock = ^{
if (modalHostView.identifier) {
[[self.bridge moduleForClass:[RCTModalManager class]] modalDismissed:modalHostView.identifier];
}
};
if (_dismissalBlock) {
_dismissalBlock([modalHostView reactViewController], viewController, animated, nil);
_dismissalBlock([modalHostView reactViewController], viewController, animated, completionBlock);
} else {
[viewController.presentingViewController dismissViewControllerAnimated:animated completion:nil];
[viewController.presentingViewController dismissViewControllerAnimated:animated completion:completionBlock];
}
}

Expand Down
17 changes: 17 additions & 0 deletions React/Views/RCTModalManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import <UIKit/UIKit.h>

#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>

@interface RCTModalManager : RCTEventEmitter <RCTBridgeModule>

- (void)modalDismissed:(NSNumber *)modalID;

@end
42 changes: 42 additions & 0 deletions React/Views/RCTModalManager.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import "RCTModalManager.h"

@interface RCTModalManager ()

@property BOOL shouldEmit;

@end

@implementation RCTModalManager

RCT_EXPORT_MODULE();

- (NSArray<NSString *> *)supportedEvents
{
return @[ @"modalDismissed" ];
}

- (void)startObserving
{
_shouldEmit = YES;
}

- (void)stopObserving
{
_shouldEmit = NO;
}

- (void)modalDismissed:(NSNumber *)modalID
{
if (_shouldEmit) {
[self sendEventWithName:@"modalDismissed" body:@{ @"modalID": modalID }];
}
}

@end

0 comments on commit 27a3248

Please sign in to comment.