Skip to content
This repository has been archived by the owner on Jan 30, 2025. It is now read-only.

Commit

Permalink
apply changes from PR - multiple modal on iOS #31498 (#29)
Browse files Browse the repository at this point in the history
* remove RCTTextView patch

* rename RCTModalHostViewInteractor

* implementing pr 31498 diff (modal works)

* nested modal example

* remove nested modal example
  • Loading branch information
fabOnReact authored Jan 30, 2024
1 parent 5229b2b commit 4c60e16
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 290 deletions.
2 changes: 2 additions & 0 deletions ios/Views/RCTModalHostViewControllerImproved.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@

@interface RCTModalHostViewControllerImproved : RCTModalHostViewController

@property RCTModalHostViewImproved* modalHostView;

@end
9 changes: 5 additions & 4 deletions ios/Views/RCTModalHostViewImproved.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@

NS_ASSUME_NONNULL_BEGIN

@protocol RCTModalHostViewInteractorImproved;
@protocol RCTModalHostViewImprovedInteractor;

@interface RCTModalHostViewImproved : RCTModalHostView

@property (nonatomic, weak) id<RCTModalHostViewInteractorImproved> delegate;
@property (nonatomic, weak) id<RCTModalHostViewImprovedInteractor> delegate;
@property (nonatomic, strong) UIWindow *modalWindow;

- (void)dismissModalViewControllerWithCompletion:(void (^)(void))completion;

@end

@protocol RCTModalHostViewInteractorImproved <NSObject>
@protocol RCTModalHostViewImprovedInteractor <NSObject>

- (void)presentModalHostView:(RCTModalHostView *)modalHostView
withViewController:(RCTModalHostViewController *)viewController
Expand All @@ -32,7 +32,8 @@ NS_ASSUME_NONNULL_BEGIN
animated:(BOOL)animated;
- (void)dismissModalHostViewWithCompletion:(RCTModalHostViewImproved *)modalHostView
withViewController:(RCTModalHostViewController *)viewController
animated:(BOOL)animated completion: (void (^)(void))completion;
animated:(BOOL)animated
completion: (void (^)(void))completion;

@end

Expand Down
15 changes: 12 additions & 3 deletions ios/Views/RCTModalHostViewImproved.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
@implementation RCTModalHostViewImproved {
__weak RCTBridge *_bridge;
BOOL _isPresented;
RCTModalHostViewController *_modalViewController;
RCTModalHostViewControllerImproved *_modalViewController;
RCTTouchHandler *_touchHandler;
UIView *_reactSubview;
UIInterfaceOrientation _lastKnownOrientation;
Expand All @@ -31,12 +31,13 @@ @implementation RCTModalHostViewImproved {
- (instancetype)initWithBridge:(RCTBridge *)bridge
{
self = [super initWithBridge:bridge];
_modalViewController = [RCTModalHostViewController new];
_modalViewController = [RCTModalHostViewControllerImproved new];
UIView *containerView = [UIView new];
containerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
_modalViewController.view = containerView;
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:bridge];
_isPresented = NO;
_modalViewController.modalHostView = self;

return self;
}
Expand Down Expand Up @@ -101,9 +102,17 @@ - (UIInterfaceOrientationMask)supportedOrientationsMask
}

- (void)dismissModalViewController
{
[self dismissModalViewControllerWithCompletion: nil];
}

- (void)dismissModalViewControllerWithCompletion:(void (^)(void))completion
{
if (_isPresented) {
[self.delegate dismissModalHostView:self withViewController:_modalViewController animated:[self hasAnimationType]];
[self.delegate dismissModalHostViewWithCompletion:self
withViewController:_modalViewController
animated:[self hasAnimationType]
completion: completion];
_isPresented = NO;
}
}
Expand Down
57 changes: 53 additions & 4 deletions ios/Views/RCTModalHostViewImprovedManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#import "RCTModalManager.h"
#import "RCTModalHostViewManager.h"

@interface RCTModalHostViewImprovedManager () <RCTModalHostViewInteractorImproved>
@interface RCTModalHostViewImprovedManager () <RCTModalHostViewImprovedInteractor>

@end

Expand Down Expand Up @@ -47,32 +47,81 @@ - (void)presentModalHostView:(RCTModalHostViewImproved *)modalHostView
if (self.presentationBlock) {
self.presentationBlock([modalHostView reactViewController], viewController, animated, completionBlock);
} else {
[[modalHostView reactViewController] presentViewController:viewController
/*
[[modalHostView reactViewController] presentViewController:viewController
animated:animated
completion:completionBlock];
*/
UIViewController* presentingViewController;
// pageSheet and formSheet presentation style animate the presented view so we need to use the last presented view controller
// For other presentation styles we use the new window
if (modalHostView.presentationStyle == UIModalPresentationPageSheet || modalHostView.presentationStyle == UIModalPresentationFormSheet) {
UIViewController *lastPresentedViewController = RCTKeyWindow().rootViewController;
UIViewController *presentedViewController = nil;
while (lastPresentedViewController != nil) {
presentedViewController = lastPresentedViewController;
lastPresentedViewController = lastPresentedViewController.presentedViewController;
}
presentingViewController = presentedViewController;
} else {
modalHostView.modalWindow = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
modalHostView.modalWindow.windowLevel = UIWindowLevelAlert;
UIViewController *newViewController = [[UIViewController alloc] init];
modalHostView.modalWindow.rootViewController = newViewController;
[modalHostView.modalWindow makeKeyAndVisible];
presentingViewController = newViewController;
}
[presentingViewController presentViewController:viewController animated:animated completion:completionBlock];
}
});
}

- (void)dismissModalHostView:(RCTModalHostViewImproved *)modalHostView
- (void)dismissModalHostViewWithCompletion:(RCTModalHostViewImproved *)modalHostView
withViewController:(RCTModalHostViewControllerImproved *)viewController
animated:(BOOL)animated
completion:(void (^)(void))completion
{
dispatch_block_t completionBlock = ^{
if (modalHostView.identifier) {
[[self.bridge moduleForClass:[RCTModalManager class]] modalDismissed:modalHostView.identifier];
}
};

if (completion) {
completion();
}
modalHostView.modalWindow = nil;

dispatch_async(dispatch_get_main_queue(), ^{
if (self.dismissalBlock) {
self.dismissalBlock([modalHostView reactViewController], viewController, animated, completionBlock);
} else {
[viewController.presentingViewController dismissViewControllerAnimated:animated completion:completionBlock];
/*
[viewController.presentingViewController dismissViewControllerAnimated:animated completion:completionBlock];
*/
// Will be true for pageSheet and formSheet presentation styles
// We dismiss the nested modal and then dismiss the current modal
if (viewController.presentedViewController != nil && [viewController.presentedViewController isKindOfClass:[RCTModalHostViewController class]]) {
RCTModalHostViewControllerImproved* presentedModalViewController = (RCTModalHostViewControllerImproved *)viewController.presentedViewController;
dispatch_block_t childModalCompletionBlock = ^{
[viewController.presentingViewController dismissViewControllerAnimated:animated completion:completionBlock];
};

[presentedModalViewController.modalHostView dismissModalViewControllerWithCompletion: childModalCompletionBlock];
} else {
[viewController.presentingViewController dismissViewControllerAnimated:animated completion:completionBlock];
}
}
});
}

- (void)dismissModalHostView:(RCTModalHostViewImproved *)modalHostView
withViewController:(RCTModalHostViewControllerImproved *)viewController
animated:(BOOL)animated
{
[self dismissModalHostViewWithCompletion:modalHostView withViewController:viewController animated:animated completion:nil];
}

- (void)invalidate
{
for (RCTModalHostView *hostView in _hostViews) {
Expand Down
Loading

0 comments on commit 4c60e16

Please sign in to comment.