fix(ios): prevent SwiftUI filter content collapse after view recycling#57643
fix(ios): prevent SwiftUI filter content collapse after view recycling#57643lujjjh wants to merge 1 commit into
Conversation
|
Hi @lujjjh! Thank you for your pull request and welcome to our community. Action RequiredIn order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you. ProcessIn order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA. Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks! |
|
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks! |
|
I don't think this is the right fix. This is doing a lot of shenaningan with the objc runtime to fix a recycle issue. |
|
@cipolleschi Thanks for the reply. I agree that the Objective-C runtime fallback deserves scrutiny. For context, the pre-iOS 16.4 fallback was adapted from an earlier Expo Modules Core implementation: Here is the RNTester Playground reproducer: https://github.com/lujjjh/react-native-swiftui-filter-repro/tree/repro/ios-swiftui-filter-recycle Detailed reproduction steps and the observed native view hierarchy are documented in #57642. One important detail is that the views mounted before recycling do not have filters. The native In the failing state, the outer My rationale for this approach is that the SwiftUI hierarchy is introduced as an implementation detail of filter rendering, and a visual filter should be layout-transparent: applying it should not change the React Native child’s geometry or safe-area behavior. This does not rule out a missing layout or safe-area invalidation during recycling, but disabling safe-area handling still seems appropriate for a filter wrapper that should not affect layout. |
|
you should avoid the safe area hack and clear the swiftUI wrapper's state in prepareForRecycle. |
9706ae6 to
b8dd946
Compare
|
@benslimanh Thanks for the suggestion. However, clearing the SwiftUI wrapper’s state in My current findings indicate that the recycle-specific collapse is caused by incomplete view-controller containment. React Native inserts the hosting controller’s view directly without attaching the hosting controller to a parent view controller. I removed the safe-area workaround and replaced it with standard containment using However, testing at the bottom of the screen shows that containment does not eliminate the need to handle safe areas. With identical filtered and unfiltered
So containment fixes the recycling lifecycle issue, but safe-area suppression is still required to keep filters layout-transparent. The remaining question is how best to implement that behavior, particularly before the public |
|
@lujjjh can you verify if passing below modifier ignores the safe area insets in original repro (without the safe area regions removal)? UIViewWrapper(view: contentView)
.ignoresSafeArea()Issue with attaching controller is that we'll also need to avoid attaching controller if the parent VC is UINavigationController or UITabBarController - here Currently i am afk, will try a more minimal repro in plain swiftui/uikit tomorrow. |

Summary:
Fixes #57642
SwiftUI-based filters can render with zero-height content after Fabric recycles a view, even though the outer React Native view and hosting view retain their expected dimensions.
This disables safe-area handling for the internal
UIHostingController, since its layout is already controlled by React Native:safeAreaRegions = []on iOS 16.4 and later.safeAreaInsetsoverride only to the hosting view instance on earlier supported versions.Changelog:
[IOS] [FIXED] - Prevent SwiftUI-based filter content from collapsing after view recycling.
Test Plan: