diff --git a/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm b/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm index 4759b6f542224d..68fbb40e258f00 100644 --- a/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm +++ b/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm @@ -61,6 +61,24 @@ - (instancetype)initWithSurface:(RCTSurface *)surface return self; } +- (void)setFrame:(CGRect)frame +{ + [super setFrame:frame]; + + CGSize minimumSize; + CGSize maximumSize; + + RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode( + self.bounds.size, + _sizeMeasureMode, + minimumSize, + maximumSize + ); + + [_surface setMinimumSize:minimumSize + maximumSize:maximumSize]; +} + - (CGSize)intrinsicContentSize { if (RCTSurfaceStageIsPreparing(_stage)) { @@ -84,24 +102,15 @@ - (CGSize)sizeThatFits:(CGSize)size return CGSizeZero; } - CGSize minimumSize = CGSizeZero; - CGSize maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX); + CGSize minimumSize; + CGSize maximumSize; - if (_sizeMeasureMode & RCTSurfaceSizeMeasureModeWidthExact) { - minimumSize.width = size.width; - maximumSize.width = size.width; - } - else if (_sizeMeasureMode & RCTSurfaceSizeMeasureModeWidthAtMost) { - maximumSize.width = size.width; - } - - if (_sizeMeasureMode & RCTSurfaceSizeMeasureModeHeightExact) { - minimumSize.height = size.height; - maximumSize.height = size.height; - } - else if (_sizeMeasureMode & RCTSurfaceSizeMeasureModeHeightAtMost) { - maximumSize.height = size.height; - } + RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode( + size, + _sizeMeasureMode, + minimumSize, + maximumSize + ); return [_surface sizeThatFitsMinimumSize:minimumSize maximumSize:maximumSize]; @@ -143,6 +152,8 @@ - (void)setIsActivityIndicatorViewVisible:(BOOL)visible return; } + _isActivityIndicatorViewVisible = visible; + if (visible) { if (_activityIndicatorViewFactory) { _activityIndicatorView = _activityIndicatorViewFactory(); @@ -164,6 +175,8 @@ - (void)setIsSurfaceViewVisible:(BOOL)visible return; } + _isSurfaceViewVisible = visible; + if (visible) { _surfaceView = _surface.view; _surfaceView.frame = self.bounds; @@ -181,7 +194,7 @@ - (void)setActivityIndicatorViewFactory:(RCTSurfaceHostingViewActivityIndicatorV { _activityIndicatorViewFactory = activityIndicatorViewFactory; if (_isActivityIndicatorViewVisible) { - _isActivityIndicatorViewVisible = NO; + self.isActivityIndicatorViewVisible = NO; self.isActivityIndicatorViewVisible = YES; } } @@ -190,6 +203,7 @@ - (void)setActivityIndicatorViewFactory:(RCTSurfaceHostingViewActivityIndicatorV - (void)_invalidateLayout { + [self invalidateIntrinsicContentSize]; [self.superview setNeedsLayout]; } diff --git a/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.h b/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.h index 825d05d96d692d..37831e4e273761 100644 --- a/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.h +++ b/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.h @@ -9,6 +9,8 @@ #import +#import + /** * Bitmask defines how size constrains from `-[UIView sizeThatFits:]` * are translated to `-[RCTSurface sizeThatFitsMinimumSize:maximumSize:]`. @@ -21,3 +23,13 @@ typedef NS_OPTIONS(NSInteger, RCTSurfaceSizeMeasureMode) { RCTSurfaceSizeMeasureModeHeightExact = 1 << 2, RCTSurfaceSizeMeasureModeHeightAtMost = 2 << 2, }; + +/** + * Returns size constraints based on `size` and `sizeMeasureMode`. + */ +RCT_EXTERN void RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode( + CGSize size, + RCTSurfaceSizeMeasureMode sizeMeasureMode, + CGSize &minimumSize, + CGSize &maximumSize +); diff --git a/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.mm b/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.mm new file mode 100644 index 00000000000000..22cada768fcd03 --- /dev/null +++ b/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.mm @@ -0,0 +1,38 @@ +/** + * 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 + +#import "RCTSurfaceSizeMeasureMode.h" + +void RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode( + CGSize size, + RCTSurfaceSizeMeasureMode sizeMeasureMode, + CGSize &minimumSize, + CGSize &maximumSize +) { + minimumSize = CGSizeZero; + maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX); + + if (sizeMeasureMode & RCTSurfaceSizeMeasureModeWidthExact) { + minimumSize.width = size.width; + maximumSize.width = size.width; + } + else if (sizeMeasureMode & RCTSurfaceSizeMeasureModeWidthAtMost) { + maximumSize.width = size.width; + } + + if (sizeMeasureMode & RCTSurfaceSizeMeasureModeHeightExact) { + minimumSize.height = size.height; + maximumSize.height = size.height; + } + else if (sizeMeasureMode & RCTSurfaceSizeMeasureModeHeightAtMost) { + maximumSize.height = size.height; + } +} diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index b86520c24f5577..f41e625e789a62 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -980,6 +980,8 @@ 590D7BFE1EBD458B00D8A370 /* RCTShadowView+Layout.h in Headers */ = {isa = PBXBuildFile; fileRef = 590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */; }; 590D7BFF1EBD458B00D8A370 /* RCTShadowView+Layout.m in Sources */ = {isa = PBXBuildFile; fileRef = 590D7BFC1EBD458B00D8A370 /* RCTShadowView+Layout.m */; }; 590D7C001EBD458B00D8A370 /* RCTShadowView+Layout.m in Sources */ = {isa = PBXBuildFile; fileRef = 590D7BFC1EBD458B00D8A370 /* RCTShadowView+Layout.m */; }; + 5925356A20084D0600DD584B /* RCTSurfaceSizeMeasureMode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5925356920084D0600DD584B /* RCTSurfaceSizeMeasureMode.mm */; }; + 5925356B20084D0600DD584B /* RCTSurfaceSizeMeasureMode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5925356920084D0600DD584B /* RCTSurfaceSizeMeasureMode.mm */; }; 59283CA01FD67321000EAAB9 /* RCTSurfaceStage.m in Sources */ = {isa = PBXBuildFile; fileRef = 59283C9F1FD67320000EAAB9 /* RCTSurfaceStage.m */; }; 59283CA11FD67321000EAAB9 /* RCTSurfaceStage.m in Sources */ = {isa = PBXBuildFile; fileRef = 59283C9F1FD67320000EAAB9 /* RCTSurfaceStage.m */; }; 594F0A321FD23228007FBE96 /* RCTSurfaceHostingView.h in Headers */ = {isa = PBXBuildFile; fileRef = 594F0A2F1FD23228007FBE96 /* RCTSurfaceHostingView.h */; }; @@ -2157,6 +2159,7 @@ 58C571C01AA56C1900CDF9C8 /* RCTDatePickerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTDatePickerManager.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 590D7BFB1EBD458B00D8A370 /* RCTShadowView+Layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTShadowView+Layout.h"; sourceTree = ""; }; 590D7BFC1EBD458B00D8A370 /* RCTShadowView+Layout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTShadowView+Layout.m"; sourceTree = ""; }; + 5925356920084D0600DD584B /* RCTSurfaceSizeMeasureMode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTSurfaceSizeMeasureMode.mm; sourceTree = ""; }; 59283C9F1FD67320000EAAB9 /* RCTSurfaceStage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTSurfaceStage.m; sourceTree = ""; }; 594F0A2F1FD23228007FBE96 /* RCTSurfaceHostingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTSurfaceHostingView.h; sourceTree = ""; }; 594F0A301FD23228007FBE96 /* RCTSurfaceHostingView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RCTSurfaceHostingView.mm; sourceTree = ""; }; @@ -2765,6 +2768,7 @@ 594F0A2F1FD23228007FBE96 /* RCTSurfaceHostingView.h */, 594F0A301FD23228007FBE96 /* RCTSurfaceHostingView.mm */, 594F0A311FD23228007FBE96 /* RCTSurfaceSizeMeasureMode.h */, + 5925356920084D0600DD584B /* RCTSurfaceSizeMeasureMode.mm */, ); path = SurfaceHostingView; sourceTree = ""; @@ -4164,6 +4168,7 @@ 3D7BFD181EA8E351008DFB7A /* RCTPackagerClient.m in Sources */, 2D3B5EA71D9B08CE00451313 /* RCTTouchHandler.m in Sources */, 59D031F01F8353D3008361F0 /* RCTSafeAreaShadowView.m in Sources */, + 5925356B20084D0600DD584B /* RCTSurfaceSizeMeasureMode.mm in Sources */, 3D05745A1DE5FFF500184BB4 /* RCTJavaScriptLoader.mm in Sources */, 2D3B5EA41D9B08C200451313 /* RCTPerformanceLogger.m in Sources */, 3DCE53251FEAB1E000613583 /* RCTShadowView.m in Sources */, @@ -4477,6 +4482,7 @@ 58114A161AAE854800E7D092 /* RCTPicker.m in Sources */, 137327E81AA5CF210034F82E /* RCTTabBarItem.m in Sources */, 83A1FE8C1B62640A00BE0E65 /* RCTModalHostView.m in Sources */, + 5925356A20084D0600DD584B /* RCTSurfaceSizeMeasureMode.mm in Sources */, 9936F3371F5F2F480010BF04 /* PrivateDataBase.cpp in Sources */, 1450FF871BCFF28A00208362 /* RCTProfileTrampoline-arm.S in Sources */, 131B6AF51AF1093D00FFC3E0 /* RCTSegmentedControlManager.m in Sources */,