Skip to content

Commit 5d1bc5a

Browse files
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.
1 parent d9ad3f0 commit 5d1bc5a

2 files changed

Lines changed: 15 additions & 3 deletions

File tree

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1746,7 +1746,13 @@ - (NSString *)componentViewName_DO_NOT_USE_THIS_IS_BROKEN
17461746

17471747
- (BOOL)styleNeedsSwiftUIContainer
17481748
{
1749-
if (!_props->filter.empty()) {
1749+
if (_props->filter.empty()) {
1750+
return NO;
1751+
}
1752+
1753+
// A filter must not affect layout, but UIHostingController insets its content by the safe area.
1754+
// To disable the insets we use `safeAreaRegions` which is only available in iOS 16.4 and tvOS 16.4.
1755+
if (@available(iOS 16.4, tvOS 16.4, *)) {
17501756
for (const auto &primitive : _props->filter) {
17511757
if (primitive.type == FilterType::Blur || primitive.type == FilterType::Grayscale ||
17521758
primitive.type == FilterType::DropShadow || primitive.type == FilterType::Saturate ||
@@ -1755,6 +1761,7 @@ - (BOOL)styleNeedsSwiftUIContainer
17551761
}
17561762
}
17571763
}
1764+
17581765
return NO;
17591766
}
17601767

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@ import UIKit
1414

1515
@objc public override init() {
1616
super.init()
17-
hostingController = UIHostingController(rootView: SwiftUIContainerView(viewModel: containerViewModel))
18-
guard let view = hostingController?.view else {
17+
let controller = UIHostingController(rootView: SwiftUIContainerView(viewModel: containerViewModel))
18+
if #available(iOS 16.4, tvOS 16.4, *) {
19+
// Disable implicit safe area insets or else the view is shifted by the safe area insets
20+
controller.safeAreaRegions = []
21+
}
22+
hostingController = controller
23+
guard let view = controller.view else {
1924
return
2025
}
2126
view.backgroundColor = .clear

0 commit comments

Comments
 (0)