Allow <Modal /> to be configured with a custom presentation/dismissal block
Reviewed By: javache, majak Differential Revision: D3751545 fbshipit-source-id: 4cf420769f7939289c0b0b70ae784328df8e2bbf
This commit is contained in:
parent
cd1d652af4
commit
d8b2bab794
|
@ -10,9 +10,13 @@
|
|||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "RCTInvalidating.h"
|
||||
#import "RCTModalHostViewManager.h"
|
||||
#import "RCTView.h"
|
||||
|
||||
@class RCTBridge;
|
||||
@class RCTModalHostViewController;
|
||||
|
||||
@protocol RCTModalHostViewInteractor;
|
||||
|
||||
@interface RCTModalHostView : UIView <RCTInvalidating>
|
||||
|
||||
|
@ -21,6 +25,15 @@
|
|||
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onShow;
|
||||
|
||||
@property (nonatomic, weak) id<RCTModalHostViewInteractor> delegate;
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@end
|
||||
|
||||
@protocol RCTModalHostViewInteractor <NSObject>
|
||||
|
||||
- (void)presentModalHostView:(RCTModalHostView *)modalHostView withViewController:(RCTModalHostViewController *)viewController animated:(BOOL)animated;
|
||||
- (void)dismissModalHostView:(RCTModalHostView *)modalHostView withViewController:(RCTModalHostViewController *)viewController animated:(BOOL)animated;
|
||||
|
||||
@end
|
||||
|
|
|
@ -83,7 +83,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
|
|||
- (void)dismissModalViewController
|
||||
{
|
||||
if (_isPresented) {
|
||||
[_modalViewController dismissViewControllerAnimated:[self hasAnimationType] completion:nil];
|
||||
[_delegate dismissModalHostView:self withViewController:_modalViewController animated:[self hasAnimationType]];
|
||||
_isPresented = NO;
|
||||
}
|
||||
}
|
||||
|
@ -100,11 +100,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
|
|||
} else if ([self.animationType isEqualToString:@"slide"]) {
|
||||
_modalViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
|
||||
}
|
||||
[self.reactViewController presentViewController:_modalViewController animated:[self hasAnimationType] completion:^{
|
||||
if (self->_onShow) {
|
||||
self->_onShow(nil);
|
||||
}
|
||||
}];
|
||||
[_delegate presentModalHostView:self withViewController:_modalViewController animated:[self hasAnimationType]];
|
||||
_isPresented = YES;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,16 @@
|
|||
|
||||
#import "RCTInvalidating.h"
|
||||
|
||||
typedef void (^RCTModalViewInteractionBlock)(UIViewController *reactViewController, UIViewController *viewController, BOOL animated, dispatch_block_t completionBlock);
|
||||
|
||||
@interface RCTModalHostViewManager : RCTViewManager <RCTInvalidating>
|
||||
|
||||
/**
|
||||
* `presentationBlock` and `dismissalBlock` allow you to control how a Modal interacts with your case,
|
||||
* e.g. in case you have a native navigator that has its own way to display a modal.
|
||||
* If these are not specified, it falls back to the UIViewController standard way of presenting.
|
||||
*/
|
||||
@property (nonatomic, strong) RCTModalViewInteractionBlock presentationBlock;
|
||||
@property (nonatomic, strong) RCTModalViewInteractionBlock dismissalBlock;
|
||||
|
||||
@end
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#import "RCTBridge.h"
|
||||
#import "RCTModalHostView.h"
|
||||
#import "RCTModalHostViewController.h"
|
||||
#import "RCTTouchHandler.h"
|
||||
#import "RCTShadowView.h"
|
||||
#import "RCTUtils.h"
|
||||
|
@ -32,6 +33,10 @@
|
|||
|
||||
@end
|
||||
|
||||
@interface RCTModalHostViewManager () <RCTModalHostViewInteractor>
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTModalHostViewManager
|
||||
{
|
||||
NSHashTable *_hostViews;
|
||||
|
@ -41,7 +46,8 @@ RCT_EXPORT_MODULE()
|
|||
|
||||
- (UIView *)view
|
||||
{
|
||||
UIView *view = [[RCTModalHostView alloc] initWithBridge:self.bridge];
|
||||
RCTModalHostView *view = [[RCTModalHostView alloc] initWithBridge:self.bridge];
|
||||
view.delegate = self;
|
||||
if (!_hostViews) {
|
||||
_hostViews = [NSHashTable weakObjectsHashTable];
|
||||
}
|
||||
|
@ -49,6 +55,30 @@ RCT_EXPORT_MODULE()
|
|||
return view;
|
||||
}
|
||||
|
||||
- (void)presentModalHostView:(RCTModalHostView *)modalHostView withViewController:(RCTModalHostViewController *)viewController animated:(BOOL)animated
|
||||
{
|
||||
dispatch_block_t completionBlock = ^{
|
||||
if (modalHostView.onShow) {
|
||||
modalHostView.onShow(nil);
|
||||
}
|
||||
};
|
||||
if (_presentationBlock) {
|
||||
_presentationBlock([modalHostView reactViewController], viewController, animated, completionBlock);
|
||||
} else {
|
||||
[[modalHostView reactViewController] presentViewController:viewController animated:animated completion:completionBlock];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dismissModalHostView:(RCTModalHostView *)modalHostView withViewController:(RCTModalHostViewController *)viewController animated:(BOOL)animated
|
||||
{
|
||||
if (_dismissalBlock) {
|
||||
_dismissalBlock([modalHostView reactViewController], viewController, animated, nil);
|
||||
} else {
|
||||
[viewController dismissViewControllerAnimated:animated completion:nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (RCTShadowView *)shadowView
|
||||
{
|
||||
return [RCTModalHostShadowView new];
|
||||
|
|
Loading…
Reference in New Issue