From 5d1bc5ab5035911e0e1703088ba73bf05e52ae4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nishan=20=28o=5E=E2=96=BD=5Eo=29?= Date: Fri, 4 Sep 2026 22:12:48 +0530 Subject: [PATCH 1/2] Stop SwiftUI-based filters from insetting content by the safe area UIHostingController insets its root view by the safe area, so a filtered view had its content moved down and shrunk whenever the view overlapped a safe area edge. A filter must not affect layout. Set `safeAreaRegions = []` on the hosting controller to opt out, and gate the SwiftUI filter container at iOS 16.4, the first version where that property exists. Below 16.4 the filters that need the container stay no-ops, which matches the behavior before `enableSwiftUIBasedFilters` existed. `safeAreaRegions` is declared `@available(iOS 16.4, tvOS 16.4, *)`, so both checks name tvOS. Without the tvOS clause the Swift file fails to build for tvOS. --- .../Mounting/ComponentViews/View/RCTViewComponentView.mm | 9 ++++++++- .../ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift | 9 +++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm index 0912c50fec13..d44d1e02ca51 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -1746,7 +1746,13 @@ - (NSString *)componentViewName_DO_NOT_USE_THIS_IS_BROKEN - (BOOL)styleNeedsSwiftUIContainer { - if (!_props->filter.empty()) { + if (_props->filter.empty()) { + return NO; + } + + // A filter must not affect layout, but UIHostingController insets its content by the safe area. + // To disable the insets we use `safeAreaRegions` which is only available in iOS 16.4 and tvOS 16.4. + if (@available(iOS 16.4, tvOS 16.4, *)) { for (const auto &primitive : _props->filter) { if (primitive.type == FilterType::Blur || primitive.type == FilterType::Grayscale || primitive.type == FilterType::DropShadow || primitive.type == FilterType::Saturate || @@ -1755,6 +1761,7 @@ - (BOOL)styleNeedsSwiftUIContainer } } } + return NO; } diff --git a/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift b/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift index 2ae423819ffb..c66afcc7c4e9 100644 --- a/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift +++ b/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift @@ -14,8 +14,13 @@ import UIKit @objc public override init() { super.init() - hostingController = UIHostingController(rootView: SwiftUIContainerView(viewModel: containerViewModel)) - guard let view = hostingController?.view else { + let controller = UIHostingController(rootView: SwiftUIContainerView(viewModel: containerViewModel)) + if #available(iOS 16.4, tvOS 16.4, *) { + // Disable implicit safe area insets or else the view is shifted by the safe area insets + controller.safeAreaRegions = [] + } + hostingController = controller + guard let view = controller.view else { return } view.backgroundColor = .clear From 1fe4d70ae69797a3acf978c9f0ce2eacc8917b46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nishan=20=28o=5E=E2=96=BD=5Eo=29?= Date: Tue, 8 Sep 2026 14:23:20 +0530 Subject: [PATCH 2/2] Assign hostingController directly instead of via a local variable --- .../ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift b/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift index c66afcc7c4e9..cf12510d1b5c 100644 --- a/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift +++ b/packages/react-native/ReactApple/RCTSwiftUI/RCTSwiftUIContainerView.swift @@ -14,13 +14,12 @@ import UIKit @objc public override init() { super.init() - let controller = UIHostingController(rootView: SwiftUIContainerView(viewModel: containerViewModel)) + hostingController = UIHostingController(rootView: SwiftUIContainerView(viewModel: containerViewModel)) if #available(iOS 16.4, tvOS 16.4, *) { // Disable implicit safe area insets or else the view is shifted by the safe area insets - controller.safeAreaRegions = [] + hostingController?.safeAreaRegions = [] } - hostingController = controller - guard let view = controller.view else { + guard let view = hostingController?.view else { return } view.backgroundColor = .clear