diff --git a/React/Views/RCTModalHostView.h b/React/Views/RCTModalHostView.h index c54c1c69c94..880b24c9a48 100644 --- a/React/Views/RCTModalHostView.h +++ b/React/Views/RCTModalHostView.h @@ -23,6 +23,7 @@ @property (nonatomic, assign, getter=isTransparent) BOOL transparent; @property (nonatomic, copy) RCTDirectEventBlock onShow; +@property (nonatomic, assign) BOOL visible; @property (nonatomic, copy) NSNumber *identifier; @@ -31,6 +32,9 @@ @property (nonatomic, copy) NSArray *supportedOrientations; @property (nonatomic, copy) RCTDirectEventBlock onOrientationChange; +// Fabric only +@property (nonatomic, copy) RCTBubblingEventBlock onDismiss; + - (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER; @end diff --git a/React/Views/RCTModalHostView.m b/React/Views/RCTModalHostView.m index 0cfa69a99aa..fa9aae7a2c1 100644 --- a/React/Views/RCTModalHostView.m +++ b/React/Views/RCTModalHostView.m @@ -119,31 +119,13 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : coder) return; } - if (!_isPresented && self.window) { - RCTAssert(self.reactViewController, @"Can't present modal view controller without a presenting view controller"); - - _modalViewController.supportedInterfaceOrientations = [self supportedOrientationsMask]; - - if ([self.animationType isEqualToString:@"fade"]) { - _modalViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; - } else if ([self.animationType isEqualToString:@"slide"]) { - _modalViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; - } - if (self.presentationStyle != UIModalPresentationNone) { - _modalViewController.modalPresentationStyle = self.presentationStyle; - } - [_delegate presentModalHostView:self withViewController:_modalViewController animated:[self hasAnimationType]]; - _isPresented = YES; - } + [self ensurePresentedOnlyIfNeeded]; } - (void)didMoveToSuperview { [super didMoveToSuperview]; - - if (_isPresented && !self.superview) { - [self dismissModalViewController]; - } + [self ensurePresentedOnlyIfNeeded]; } - (void)invalidate @@ -163,6 +145,40 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : coder) return ![self.animationType isEqualToString:@"none"]; } +- (void)setVisible:(BOOL)visible +{ + if (_visible != visible) { + _visible = visible; + [self ensurePresentedOnlyIfNeeded]; + } +} + +- (void)ensurePresentedOnlyIfNeeded +{ + BOOL shouldBePresented = !_isPresented && _visible && self.window; + if (shouldBePresented) { + RCTAssert(self.reactViewController, @"Can't present modal view controller without a presenting view controller"); + + _modalViewController.supportedInterfaceOrientations = [self supportedOrientationsMask]; + + if ([self.animationType isEqualToString:@"fade"]) { + _modalViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; + } else if ([self.animationType isEqualToString:@"slide"]) { + _modalViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; + } + if (self.presentationStyle != UIModalPresentationNone) { + _modalViewController.modalPresentationStyle = self.presentationStyle; + } + [_delegate presentModalHostView:self withViewController:_modalViewController animated:[self hasAnimationType]]; + _isPresented = YES; + } + + BOOL shouldBeHidden = _isPresented && (!_visible || !self.superview); + if (shouldBeHidden) { + [self dismissModalViewController]; + } +} + - (void)setTransparent:(BOOL)transparent { if (self.isTransparent != transparent) { diff --git a/React/Views/RCTModalHostViewManager.m b/React/Views/RCTModalHostViewManager.m index 5304d41cf5e..7ca197d5866 100644 --- a/React/Views/RCTModalHostViewManager.m +++ b/React/Views/RCTModalHostViewManager.m @@ -120,9 +120,9 @@ RCT_EXPORT_VIEW_PROPERTY(onShow, RCTDirectEventBlock) RCT_EXPORT_VIEW_PROPERTY(identifier, NSNumber) RCT_EXPORT_VIEW_PROPERTY(supportedOrientations, NSArray) RCT_EXPORT_VIEW_PROPERTY(onOrientationChange, RCTDirectEventBlock) +RCT_EXPORT_VIEW_PROPERTY(visible, BOOL) // Fabric only -RCT_EXPORT_VIEW_PROPERTY(visible, BOOL) RCT_EXPORT_VIEW_PROPERTY(onDismiss, RCTDirectEventBlock) @end