Skip to content

Commit b8dd946

Browse files
committed
fix(ios): prevent SwiftUI filter content collapse
1 parent ad870da commit b8dd946

4 files changed

Lines changed: 65 additions & 2 deletions

File tree

packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#import <React/RCTLocalizedString.h>
2424
#import <React/RCTLog.h>
2525
#import <React/RCTRadialGradient.h>
26+
#import <React/UIView+React.h>
2627
#import <react/featureflags/ReactNativeFeatureFlags.h>
2728
#import <react/renderer/components/view/ViewComponentDescriptor.h>
2829
#import <react/renderer/components/view/ViewEventEmitter.h>
@@ -726,6 +727,23 @@ - (void)prepareForRecycle
726727
_layoutMetrics = {};
727728
}
728729

730+
- (void)updateSwiftUIWrapperAttachment
731+
{
732+
if (_swiftUIWrapper == nullptr) {
733+
return;
734+
}
735+
736+
if (self.window == nil) {
737+
[_swiftUIWrapper detachFromParentViewController];
738+
return;
739+
}
740+
741+
UIViewController *parentViewController = self.reactViewController;
742+
if (parentViewController != nil) {
743+
[_swiftUIWrapper attachToParentViewController:parentViewController inContainerView:self];
744+
}
745+
}
746+
729747
- (void)setPropKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN:(NSSet<NSString *> *_Nullable)props
730748
{
731749
_propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN = props;
@@ -927,7 +945,7 @@ - (UIView *)effectiveContentView
927945
self.layer.mask = nil;
928946
[_swiftUIWrapper updateContentView:swiftUIContentView];
929947
[_swiftUIWrapper updateLayoutWithBounds:self.bounds];
930-
[self addSubview:_swiftUIWrapper.hostingView];
948+
[self updateSwiftUIWrapperAttachment];
931949

932950
[self transferVisualPropertiesFromView:self toView:swiftUIContentView];
933951
}
@@ -944,7 +962,7 @@ - (UIView *)effectiveContentView
944962

945963
[self transferVisualPropertiesFromView:swiftUIContentView toView:self];
946964

947-
[_swiftUIWrapper.hostingView removeFromSuperview];
965+
[_swiftUIWrapper detachFromParentViewController];
948966
_swiftUIWrapper = nil;
949967
}
950968
}
@@ -1401,6 +1419,12 @@ - (void)didMoveToSuperview
14011419
}
14021420
}
14031421

1422+
- (void)didMoveToWindow
1423+
{
1424+
[super didMoveToWindow];
1425+
[self updateSwiftUIWrapperAttachment];
1426+
}
1427+
14041428
- (void)updateAccessibilityElements
14051429
{
14061430
if ([_accessibilityOrderNativeIDs count] == 0) {

packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,33 @@ import UIKit
2929
return hostingController?.view
3030
}
3131

32+
@objc public func attach(to parentViewController: UIViewController, in containerView: UIView) {
33+
guard let hostingController else {
34+
return
35+
}
36+
37+
if hostingController.parent === parentViewController && hostingController.view.superview === containerView {
38+
return
39+
}
40+
41+
detachFromParentViewController()
42+
parentViewController.addChild(hostingController)
43+
containerView.addSubview(hostingController.view)
44+
hostingController.didMove(toParent: parentViewController)
45+
}
46+
47+
@objc public func detachFromParentViewController() {
48+
guard let hostingController else {
49+
return
50+
}
51+
52+
if hostingController.parent != nil {
53+
hostingController.willMove(toParent: nil)
54+
}
55+
hostingController.view.removeFromSuperview()
56+
hostingController.removeFromParent()
57+
}
58+
3259
@objc public func contentView() -> UIView? {
3360
return containerViewModel.contentView
3461
}

packages/react-native/ReactApple/RCTSwiftUIWrapper/RCTSwiftUIContainerViewWrapper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ NS_ASSUME_NONNULL_BEGIN
2121
- (void)updateHueRotate:(NSNumber *)degrees;
2222
- (void)updateContentView:(UIView *)view;
2323
- (UIView *_Nullable)hostingView;
24+
- (void)attachToParentViewController:(UIViewController *)parentViewController inContainerView:(UIView *)containerView;
25+
- (void)detachFromParentViewController;
2426
- (void)resetStyles;
2527
- (void)updateLayoutWithBounds:(CGRect)bounds;
2628

packages/react-native/ReactApple/RCTSwiftUIWrapper/RCTSwiftUIContainerViewWrapper.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,16 @@ - (UIView *_Nullable)hostingView
3333
return [self.swiftContainerView hostingView];
3434
}
3535

36+
- (void)attachToParentViewController:(UIViewController *)parentViewController inContainerView:(UIView *)containerView
37+
{
38+
[self.swiftContainerView attachTo:parentViewController in:containerView];
39+
}
40+
41+
- (void)detachFromParentViewController
42+
{
43+
[self.swiftContainerView detachFromParentViewController];
44+
}
45+
3646
- (void)resetStyles
3747
{
3848
[self.swiftContainerView resetStyles];

0 commit comments

Comments
 (0)