Add onDismiss to Modal.js
Summary: Adds an onDismiss so that navigation events can be chained to the dismissing of a modal. Reviewed By: sahrens Differential Revision: D5852953 fbshipit-source-id: a86e36fdd5b0b206c2dd9fa248e2a88da22efa31
This commit is contained in:
parent
dd87db392d
commit
a389ffbd84
|
@ -13,6 +13,8 @@
|
|||
|
||||
const AppContainer = require('AppContainer');
|
||||
const I18nManager = require('I18nManager');
|
||||
const NativeEventEmitter = require('NativeEventEmitter');
|
||||
const NativeModules = require('NativeModules');
|
||||
const Platform = require('Platform');
|
||||
const React = require('React');
|
||||
const PropTypes = require('prop-types');
|
||||
|
@ -22,6 +24,10 @@ const View = require('View');
|
|||
const deprecatedPropType = require('deprecatedPropType');
|
||||
const requireNativeComponent = require('requireNativeComponent');
|
||||
const RCTModalHostView = requireNativeComponent('RCTModalHostView', null);
|
||||
const ModalEventEmitter = Platform.OS === 'ios' && NativeModules.ModalManager ?
|
||||
new NativeEventEmitter(NativeModules.ModalManager) : null;
|
||||
|
||||
import type EmitterSubscription from 'EmitterSubscription';
|
||||
|
||||
/**
|
||||
* The Modal component is a simple way to present content above an enclosing view.
|
||||
|
@ -79,6 +85,12 @@ const RCTModalHostView = requireNativeComponent('RCTModalHostView', null);
|
|||
* ```
|
||||
*/
|
||||
|
||||
// In order to route onDismiss callbacks, we need to uniquely identifier each
|
||||
// <Modal> on screen. There can be different ones, either nested or as siblings.
|
||||
// We cannot pass the onDismiss callback to native as the view will be
|
||||
// destroyed before the callback is fired.
|
||||
var uniqueModalIdentifier = 0;
|
||||
|
||||
class Modal extends React.Component<Object> {
|
||||
static propTypes = {
|
||||
/**
|
||||
|
@ -125,6 +137,11 @@ class Modal extends React.Component<Object> {
|
|||
* The `onShow` prop allows passing a function that will be called once the modal has been shown.
|
||||
*/
|
||||
onShow: PropTypes.func,
|
||||
/**
|
||||
* The `onDismiss` prop allows passing a function that will be called once the modal has been dismissed.
|
||||
* @platform ios
|
||||
*/
|
||||
onDismiss: PropTypes.func,
|
||||
animated: deprecatedPropType(
|
||||
PropTypes.bool,
|
||||
'Use the `animationType` prop instead.'
|
||||
|
@ -153,9 +170,32 @@ class Modal extends React.Component<Object> {
|
|||
rootTag: PropTypes.number,
|
||||
};
|
||||
|
||||
_identifier: number;
|
||||
_eventSubscription: ?EmitterSubscription;
|
||||
|
||||
constructor(props: Object) {
|
||||
super(props);
|
||||
Modal._confirmProps(props);
|
||||
this._identifier = uniqueModalIdentifier++;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (ModalEventEmitter) {
|
||||
this._eventSubscription = ModalEventEmitter.addListener(
|
||||
'modalDismissed',
|
||||
event => {
|
||||
if (event.modalID === this._identifier && this.props.onDismiss) {
|
||||
this.props.onDismiss();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this._eventSubscription) {
|
||||
this._eventSubscription.remove();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps: Object) {
|
||||
|
@ -208,6 +248,7 @@ class Modal extends React.Component<Object> {
|
|||
hardwareAccelerated={this.props.hardwareAccelerated}
|
||||
onRequestClose={this.props.onRequestClose}
|
||||
onShow={this.props.onShow}
|
||||
identifier={this._identifier}
|
||||
style={styles.modal}
|
||||
onStartShouldSetResponder={this._shouldSetResponder}
|
||||
supportedOrientations={this.props.supportedOrientations}
|
||||
|
|
|
@ -1071,6 +1071,7 @@
|
|||
83CBBA691A601EF300E9B192 /* RCTEventDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */; };
|
||||
83CBBA981A6020BB00E9B192 /* RCTTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */; };
|
||||
83CBBACC1A6023D300E9B192 /* RCTConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBACB1A6023D300E9B192 /* RCTConvert.m */; };
|
||||
916F9C2D1F743F57002E5920 /* RCTModalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 91076A871F743AB00081B4FA /* RCTModalManager.m */; };
|
||||
9936F3371F5F2F480010BF04 /* PrivateDataBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9936F3351F5F2F480010BF04 /* PrivateDataBase.cpp */; };
|
||||
9936F3381F5F2F480010BF04 /* PrivateDataBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 9936F3361F5F2F480010BF04 /* PrivateDataBase.h */; };
|
||||
9936F3391F5F2F5C0010BF04 /* PrivateDataBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 9936F3361F5F2F480010BF04 /* PrivateDataBase.h */; };
|
||||
|
@ -2084,6 +2085,8 @@
|
|||
83CBBACA1A6023D300E9B192 /* RCTConvert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTConvert.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
83CBBACB1A6023D300E9B192 /* RCTConvert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert.m; sourceTree = "<group>"; };
|
||||
83F15A171B7CC46900F10295 /* UIView+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIView+Private.h"; sourceTree = "<group>"; };
|
||||
91076A871F743AB00081B4FA /* RCTModalManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTModalManager.m; sourceTree = "<group>"; };
|
||||
91076A881F743AB00081B4FA /* RCTModalManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTModalManager.h; sourceTree = "<group>"; };
|
||||
9936F3131F5F2E4B0010BF04 /* libprivatedata.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libprivatedata.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9936F32F1F5F2E5B0010BF04 /* libprivatedata-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libprivatedata-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
9936F3351F5F2F480010BF04 /* PrivateDataBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PrivateDataBase.cpp; path = privatedata/PrivateDataBase.cpp; sourceTree = "<group>"; };
|
||||
|
@ -2373,6 +2376,8 @@
|
|||
83392EB21B6634E10013B15F /* RCTModalHostViewController.m */,
|
||||
83A1FE8D1B62643A00BE0E65 /* RCTModalHostViewManager.h */,
|
||||
83A1FE8E1B62643A00BE0E65 /* RCTModalHostViewManager.m */,
|
||||
91076A881F743AB00081B4FA /* RCTModalManager.h */,
|
||||
91076A871F743AB00081B4FA /* RCTModalManager.m */,
|
||||
13B0800C1A69489C00A75B9A /* RCTNavigator.h */,
|
||||
13B0800D1A69489C00A75B9A /* RCTNavigator.m */,
|
||||
13B0800E1A69489C00A75B9A /* RCTNavigatorManager.h */,
|
||||
|
@ -4144,6 +4149,7 @@
|
|||
1450FF861BCFF28A00208362 /* RCTProfile.m in Sources */,
|
||||
13AB90C11B6FA36700713B4F /* RCTComponentData.m in Sources */,
|
||||
13B0801B1A69489C00A75B9A /* RCTNavigatorManager.m in Sources */,
|
||||
916F9C2D1F743F57002E5920 /* RCTModalManager.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
@ -725,6 +725,7 @@
|
|||
83CBBA691A601EF300E9B192 /* RCTEventDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA661A601EF300E9B192 /* RCTEventDispatcher.m */; };
|
||||
83CBBA981A6020BB00E9B192 /* RCTTouchHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */; };
|
||||
83CBBACC1A6023D300E9B192 /* RCTConvert.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CBBACB1A6023D300E9B192 /* RCTConvert.m */; };
|
||||
916F9C2E1F743F7E002E5920 /* RCTModalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 91076A891F743AD70081B4FA /* RCTModalManager.m */; };
|
||||
945929C41DD62ADD00653A7D /* RCTConvert+Transform.m in Sources */ = {isa = PBXBuildFile; fileRef = 945929C31DD62ADD00653A7D /* RCTConvert+Transform.m */; };
|
||||
945929C51DD62ADD00653A7D /* RCTConvert+Transform.m in Sources */ = {isa = PBXBuildFile; fileRef = 945929C31DD62ADD00653A7D /* RCTConvert+Transform.m */; };
|
||||
A12E9E1B1E5DEA350029001B /* RCTPackagerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = A12E9E171E5DEA350029001B /* RCTPackagerClient.h */; };
|
||||
|
@ -1412,6 +1413,8 @@
|
|||
83CBBACA1A6023D300E9B192 /* RCTConvert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTConvert.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
83CBBACB1A6023D300E9B192 /* RCTConvert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert.m; sourceTree = "<group>"; };
|
||||
83F15A171B7CC46900F10295 /* UIView+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIView+Private.h"; sourceTree = "<group>"; };
|
||||
91076A891F743AD70081B4FA /* RCTModalManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTModalManager.m; sourceTree = "<group>"; };
|
||||
91076A8A1F743AD70081B4FA /* RCTModalManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTModalManager.h; sourceTree = "<group>"; };
|
||||
945929C21DD62ADD00653A7D /* RCTConvert+Transform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+Transform.h"; sourceTree = "<group>"; };
|
||||
945929C31DD62ADD00653A7D /* RCTConvert+Transform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+Transform.m"; sourceTree = "<group>"; };
|
||||
A12E9E171E5DEA350029001B /* RCTPackagerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTPackagerClient.h; sourceTree = "<group>"; };
|
||||
|
@ -1587,6 +1590,8 @@
|
|||
83392EB21B6634E10013B15F /* RCTModalHostViewController.m */,
|
||||
83A1FE8D1B62643A00BE0E65 /* RCTModalHostViewManager.h */,
|
||||
83A1FE8E1B62643A00BE0E65 /* RCTModalHostViewManager.m */,
|
||||
91076A8A1F743AD70081B4FA /* RCTModalManager.h */,
|
||||
91076A891F743AD70081B4FA /* RCTModalManager.m */,
|
||||
13B0800C1A69489C00A75B9A /* RCTNavigator.h */,
|
||||
13B0800D1A69489C00A75B9A /* RCTNavigator.m */,
|
||||
13B0800E1A69489C00A75B9A /* RCTNavigatorManager.h */,
|
||||
|
@ -2700,6 +2705,7 @@
|
|||
597AD1BF1E577D7800152581 /* RCTRootContentView.m in Sources */,
|
||||
13723B501A82FD3C00F88898 /* RCTStatusBarManager.m in Sources */,
|
||||
000E6CEB1AB0E980000CDF4D /* RCTSourceCode.m in Sources */,
|
||||
916F9C2E1F743F7E002E5920 /* RCTModalManager.m in Sources */,
|
||||
001BFCD01D8381DE008E587E /* RCTMultipartStreamReader.m in Sources */,
|
||||
133CAE8E1B8E5CFD00F6AD92 /* RCTDatePicker.m in Sources */,
|
||||
14C2CA761B3AC64F00E6CBB2 /* RCTFrameUpdate.m in Sources */,
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onShow;
|
||||
|
||||
@property (nonatomic, copy) NSNumber *identifier;
|
||||
|
||||
@property (nonatomic, weak) id<RCTModalHostViewInteractor> delegate;
|
||||
|
||||
@property (nonatomic, copy) NSArray<NSString *> *supportedOrientations;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#import "RCTBridge.h"
|
||||
#import "RCTModalHostView.h"
|
||||
#import "RCTModalHostViewController.h"
|
||||
#import "RCTModalManager.h"
|
||||
#import "RCTShadowView.h"
|
||||
#import "RCTUtils.h"
|
||||
|
||||
|
@ -82,10 +83,15 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
- (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 dismissViewControllerAnimated:animated completion:nil];
|
||||
[viewController dismissViewControllerAnimated:animated completion:completionBlock];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,6 +113,7 @@ RCT_EXPORT_VIEW_PROPERTY(animationType, NSString)
|
|||
RCT_EXPORT_VIEW_PROPERTY(presentationStyle, UIModalPresentationStyle)
|
||||
RCT_EXPORT_VIEW_PROPERTY(transparent, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onShow, RCTDirectEventBlock)
|
||||
RCT_EXPORT_VIEW_PROPERTY(identifier, NSNumber)
|
||||
RCT_EXPORT_VIEW_PROPERTY(supportedOrientations, NSArray)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onOrientationChange, RCTDirectEventBlock)
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTEventEmitter.h>
|
||||
|
||||
@interface RCTModalManager : RCTEventEmitter <RCTBridgeModule>
|
||||
|
||||
- (void)modalDismissed:(NSNumber *)modalID;
|
||||
|
||||
@end
|
|
@ -0,0 +1,26 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "RCTModalManager.h"
|
||||
|
||||
@implementation RCTModalManager
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents
|
||||
{
|
||||
return @[ @"modalDismissed" ];
|
||||
}
|
||||
|
||||
- (void)modalDismissed:(NSNumber *)modalID
|
||||
{
|
||||
[self sendEventWithName:@"modalDismissed" body:@{ @"modalID": modalID }];
|
||||
}
|
||||
|
||||
@end
|
Loading…
Reference in New Issue