NavigationView 无法为容器视图控制器配置正确尺寸的问题
2024-02-01 15:43:06
问题概述
在使用SwiftUI构建iOS应用时,如果您使用NavigationView作为导航视图,可能会遇到这样一个问题:当您在NavigationView中放置一个容器视图控制器时,容器视图控制器的大小无法正确配置,导致子视图无法正常显示。例如,如果将一个UINavigationController作为NavigationView的根视图控制器,那么UINavigationController的navigationBar和toolBar可能会遮挡住UINavigationController的子视图控制器。
问题分析
这个问题的根源在于UIKit和SwiftUI这两个框架之间的数据交换和视图转换的方式。UIKit使用UIView作为视图的基类,而SwiftUI使用UIViewRepresentable协议来将SwiftUI视图转换为UIKit视图。当您在NavigationView中放置一个容器视图控制器时,SwiftUI会创建一个UIViewRepresentable实例来将容器视图控制器转换为UIKit视图。这个UIViewRepresentable实例负责将容器视图控制器的子视图控制器转换为UIKit视图,并将其添加到容器视图控制器的视图层次结构中。
问题在于,UIViewRepresentable实例在转换容器视图控制器的子视图控制器时,并没有正确地配置子视图控制器的视图大小。具体来说,UIViewRepresentable实例并没有将容器视图控制器的子视图控制器的视图大小设置为与容器视图控制器视图的大小相同。这导致容器视图控制器的子视图控制器无法正常显示,并且可能会被导航栏、工具栏、边距和安全区域遮挡。
解决方案
这个问题目前还没有一个完美的解决方案。一种可能的解决方案是手动配置容器视图控制器的子视图控制器的视图大小。您可以使用UIKit框架中的setFrame()方法来设置子视图控制器的视图大小。例如,您可以使用以下代码来设置UINavigationController的子视图控制器的视图大小:
let navigationController = UINavigationController()
let childViewController = UIViewController()
childViewController.view.frame = navigationController.view.bounds
navigationController.pushViewController(childViewController, animated: false)
另一种可能的解决方案是使用SwiftUI的frame(width:height:)修饰符来设置容器视图控制器的子视图控制器的视图大小。例如,您可以使用以下代码来设置UINavigationController的子视图控制器的视图大小:
NavigationView {
NavigationLink(destination: UIHostingController(rootView: ChildView()))
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
}
结论
这个问题是一个SwiftUI框架中存在的已知问题。目前还没有一个完美的解决方案。您可以使用手动配置容器视图控制器的子视图控制器的视图大小或使用SwiftUI的frame(width:height:)修饰符来设置容器视图控制器的子视图控制器的视图大小来解决这个问题。