Skip to content

Commit

Permalink
Allow <Modal /> to be configured with a custom presentation/dismissal…
Browse files Browse the repository at this point in the history
… block

Reviewed By: javache, majak

Differential Revision: D3751545

fbshipit-source-id: 4cf420769f7939289c0b0b70ae784328df8e2bbf
  • Loading branch information
Mehdi Mulani authored and Facebook Github Bot 0 committed Aug 23, 2016
1 parent cd1d652 commit d8b2bab
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 7 deletions.
13 changes: 13 additions & 0 deletions React/Views/RCTModalHostView.h
Expand Up @@ -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>

Expand All @@ -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
8 changes: 2 additions & 6 deletions React/Views/RCTModalHostView.m
Expand Up @@ -83,7 +83,7 @@ - (void)didUpdateReactSubviews
- (void)dismissModalViewController
{
if (_isPresented) {
[_modalViewController dismissViewControllerAnimated:[self hasAnimationType] completion:nil];
[_delegate dismissModalHostView:self withViewController:_modalViewController animated:[self hasAnimationType]];
_isPresented = NO;
}
}
Expand All @@ -100,11 +100,7 @@ - (void)didMoveToWindow
} 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;
}
}
Expand Down
10 changes: 10 additions & 0 deletions React/Views/RCTModalHostViewManager.h
Expand Up @@ -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
32 changes: 31 additions & 1 deletion React/Views/RCTModalHostViewManager.m
Expand Up @@ -11,6 +11,7 @@

#import "RCTBridge.h"
#import "RCTModalHostView.h"
#import "RCTModalHostViewController.h"
#import "RCTTouchHandler.h"
#import "RCTShadowView.h"
#import "RCTUtils.h"
Expand All @@ -32,6 +33,10 @@ - (void)insertReactSubview:(id<RCTComponent>)subview atIndex:(NSInteger)atIndex

@end

@interface RCTModalHostViewManager () <RCTModalHostViewInteractor>

@end

@implementation RCTModalHostViewManager
{
NSHashTable *_hostViews;
Expand All @@ -41,14 +46,39 @@ @implementation RCTModalHostViewManager

- (UIView *)view
{
UIView *view = [[RCTModalHostView alloc] initWithBridge:self.bridge];
RCTModalHostView *view = [[RCTModalHostView alloc] initWithBridge:self.bridge];
view.delegate = self;
if (!_hostViews) {
_hostViews = [NSHashTable weakObjectsHashTable];
}
[_hostViews addObject:view];
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];
Expand Down

0 comments on commit d8b2bab

Please sign in to comment.