mirror of
https://github.com/status-im/react-native.git
synced 2025-01-10 01:25:39 +00:00
85f7569ce6
Summary:We had an issue where a rendered modal would not end up using the full screen size, but a size computed based on its initial content. Which is a small spinner in case of RelayContainer. So rarely we would end up with cut off view like this: {F60650629} This diff fixes this behavior by wrapping the content in another view. That makes the modal's wrapping VC's view resize just once when it's initially created. (Resize for the wrapping VC's view happened previously when the modal's content resized, which got us in the bad state.) Reviewed By: javache Differential Revision: D3202299 fb-gh-sync-id: 7c4dc1dbb27654292d07aef5916aa31df5cd4302 fbshipit-source-id: 7c4dc1dbb27654292d07aef5916aa31df5cd4302
132 lines
3.5 KiB
Objective-C
132 lines
3.5 KiB
Objective-C
/**
|
|
* 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 "RCTModalHostView.h"
|
|
|
|
#import "RCTAssert.h"
|
|
#import "RCTBridge.h"
|
|
#import "RCTModalHostViewController.h"
|
|
#import "RCTTouchHandler.h"
|
|
#import "RCTUIManager.h"
|
|
#import "UIView+React.h"
|
|
|
|
@implementation RCTModalHostView
|
|
{
|
|
__weak RCTBridge *_bridge;
|
|
BOOL _isPresented;
|
|
RCTModalHostViewController *_modalViewController;
|
|
RCTTouchHandler *_touchHandler;
|
|
UIView *_reactSubview;
|
|
}
|
|
|
|
RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
|
|
RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:coder)
|
|
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
|
{
|
|
if ((self = [super initWithFrame:CGRectZero])) {
|
|
_bridge = bridge;
|
|
_modalViewController = [RCTModalHostViewController new];
|
|
UIView *containerView = [UIView new];
|
|
containerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
|
|
_modalViewController.view = containerView;
|
|
_touchHandler = [[RCTTouchHandler alloc] initWithBridge:bridge];
|
|
_isPresented = NO;
|
|
|
|
__weak typeof(self) weakSelf = self;
|
|
_modalViewController.boundsDidChangeBlock = ^(CGRect newBounds) {
|
|
[weakSelf notifyForBoundsChange:newBounds];
|
|
};
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)notifyForBoundsChange:(CGRect)newBounds
|
|
{
|
|
if (_reactSubview && _isPresented) {
|
|
[_bridge.uiManager setFrame:newBounds forView:_reactSubview];
|
|
}
|
|
}
|
|
|
|
- (NSArray<UIView *> *)reactSubviews
|
|
{
|
|
return _reactSubview ? @[_reactSubview] : @[];
|
|
}
|
|
|
|
- (void)insertReactSubview:(UIView *)subview atIndex:(__unused NSInteger)atIndex
|
|
{
|
|
RCTAssert(_reactSubview == nil, @"Modal view can only have one subview");
|
|
[subview addGestureRecognizer:_touchHandler];
|
|
subview.autoresizingMask = UIViewAutoresizingFlexibleHeight |
|
|
UIViewAutoresizingFlexibleWidth;
|
|
|
|
[_modalViewController.view insertSubview:subview atIndex:0];
|
|
_reactSubview = subview;
|
|
}
|
|
|
|
- (void)removeReactSubview:(UIView *)subview
|
|
{
|
|
RCTAssert(subview == _reactSubview, @"Cannot remove view other than modal view");
|
|
[subview removeGestureRecognizer:_touchHandler];
|
|
[subview removeFromSuperview];
|
|
_reactSubview = nil;
|
|
}
|
|
|
|
- (void)dismissModalViewController
|
|
{
|
|
if (_isPresented) {
|
|
[_modalViewController dismissViewControllerAnimated:self.animated completion:nil];
|
|
_isPresented = NO;
|
|
}
|
|
}
|
|
|
|
- (void)didMoveToWindow
|
|
{
|
|
[super didMoveToWindow];
|
|
|
|
if (!_isPresented && self.window) {
|
|
RCTAssert(self.reactViewController, @"Can't present modal view controller without a presenting view controller");
|
|
[self.reactViewController presentViewController:_modalViewController animated:self.animated completion:^{
|
|
if (_onShow) {
|
|
_onShow(nil);
|
|
}
|
|
}];
|
|
_isPresented = YES;
|
|
}
|
|
}
|
|
|
|
- (void)didMoveToSuperview
|
|
{
|
|
[super didMoveToSuperview];
|
|
|
|
if (_isPresented && !self.superview) {
|
|
[self dismissModalViewController];
|
|
}
|
|
}
|
|
|
|
- (void)invalidate
|
|
{
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
[self dismissModalViewController];
|
|
});
|
|
}
|
|
|
|
- (BOOL)isTransparent
|
|
{
|
|
return _modalViewController.modalPresentationStyle == UIModalPresentationCustom;
|
|
}
|
|
|
|
- (void)setTransparent:(BOOL)transparent
|
|
{
|
|
_modalViewController.modalPresentationStyle = transparent ? UIModalPresentationCustom : UIModalPresentationFullScreen;
|
|
}
|
|
|
|
@end
|