iOS16中SwiftUI使用UIViewControllerRepresentable时UIHostingController内容被裁剪问题
针对iOS 16下,在NavigationView内通过UIViewControllerRepresentable使用UIHostingController,跳转返回后内容被裁剪的问题,可通过以下方式修复:
解决方案
修改TosterView的实现,确保UIHostingController的根视图填充整个控制器视图,并在返回后强制刷新布局:
import SwiftUI struct ContentView: View { var body: some View { NavigationView { ScrollView { VStack { TosterView { Color.green } .frame(height: 170) NavigationLink(destination: { Text("Destination")}, label: { Text("Go to destination")}) Color.orange.frame(height: 900) } } } } } public struct TosterView<PageContent: View>: UIViewControllerRepresentable { let contentForData: () -> PageContent public func makeUIViewController(context: Context) -> UIHostingController<PageContent> { // 给根视图添加无限宽高的frame,确保内容填充整个控制器视图 let rootView = contentForData() .frame(maxWidth: .infinity, maxHeight: .infinity) let hostingController = UIHostingController(rootView: rootView) // 禁用自动约束转换,让SwiftUI布局系统控制尺寸 hostingController.view.translatesAutoresizingMaskIntoConstraints = false return hostingController } public func updateUIViewController(_ uiViewController: UIHostingController<PageContent>, context: Context) { // 更新根视图并异步强制刷新布局,修复返回后的尺寸异常 uiViewController.rootView = contentForData() .frame(maxWidth: .infinity, maxHeight: .infinity) DispatchQueue.main.async { uiViewController.view.setNeedsLayout() uiViewController.view.layoutIfNeeded() } } }
问题原因
iOS 16中,NavigationView的导航栈切换后,ScrollView的布局回流可能导致UIHostingController的视图尺寸未正确更新,而默认的UIHostingController根视图没有强制填充整个控制器视图,最终引发内容裁剪。通过给根视图添加无限宽高的frame,确保内容始终填充控制器视图;同时在updateUIViewController中异步刷新布局,保证返回后尺寸约束正确应用。
内容的提问来源于stack exchange,提问作者Mixorok
相关产品推荐
相关产品推荐

