如何在UIKit ViewController中嵌入SwiftUI Chart?编译正常但无UI显示
解决Storyboard中嵌入SwiftUI Chart不显示的问题
你的代码存在几个关键问题,导致图表无法显示,以下是问题分析和修正方案:
核心问题点
- 视图类型匹配错误:你定义的SwiftUI图表视图是
ContentViewChart,但创建实例时误用了ContentView(),加载的不是目标视图。 - 容器视图未加入层级:创建的蓝色主容器
uiView没有添加到当前ViewController的视图层级中,整个容器都不在界面上。 - Host View无布局约束:将SwiftUI视图的宿主View添加到容器后,未设置尺寸约束,导致SwiftUI视图没有显示空间。
- 方法内定义结构体不规范:在
viewDidLoad内定义Item和ContentViewChart虽能编译,但不符合Swift编码规范,易引发潜在问题。
修正后的完整代码
// 将结构体移到ViewController类外部,符合编码规范 struct Item: Identifiable { var id = UUID() let type: String let value: Double } struct ContentViewChart: View { let items: [Item] = [ Item(type: "1", value: 100 ), Item(type: "2", value: 80 ), Item(type: "3", value: 120 ), Item(type: "4", value: 20 ), Item(type: "5", value: 55 ), Item(type: "6", value: 170 ), Item(type: "7", value: 20 ), Item(type: "8", value: 10 ), Item(type: "9", value: 5 ), Item(type: "10", value: 1 ), Item(type: "11", value: 500 ), Item(type: "12", value: 700 ) ] var body: some View { // 移除不必要的NavigationView,避免额外导航栏占用空间 ScrollView { Chart(items) { item in LineMark( x: .value("Month", item.type), y: .value("Revenue", item.value) ) .foregroundStyle(Color.purple.gradient) } .frame(height: 200) .padding() } } } class YourViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Revenue Chart let size = CGSize(width: 400, height: 400) let sizeSubView = CGSize(width: 200, height: 200) let uiView = UIView(frame: CGRect(origin: .zero, size: size)) uiView.backgroundColor = .systemBlue // 将主容器添加到当前VC的视图层级 view.addSubview(uiView) // 通过约束固定主容器位置(居中显示) uiView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ uiView.centerXAnchor.constraint(equalTo: view.centerXAnchor), uiView.centerYAnchor.constraint(equalTo: view.centerYAnchor), uiView.widthAnchor.constraint(equalToConstant: size.width), uiView.heightAnchor.constraint(equalToConstant: size.height) ]) let centerPointForSubView = CGRect(origin: CGPoint(x: 100, y: 100), size: sizeSubView) let uiViewSubView = UIView(frame: centerPointForSubView) uiViewSubView.backgroundColor = .white uiView.addSubview(uiViewSubView) // 创建正确的SwiftUI视图实例 let swiftUIView = ContentViewChart() let host = UIHostingController(rootView: swiftUIView) let hostView = host.view! // 设置Host View填充整个容器子视图 hostView.translatesAutoresizingMaskIntoConstraints = false uiViewSubView.addSubview(hostView) NSLayoutConstraint.activate([ hostView.topAnchor.constraint(equalTo: uiViewSubView.topAnchor), hostView.leadingAnchor.constraint(equalTo: uiViewSubView.leadingAnchor), hostView.trailingAnchor.constraint(equalTo: uiViewSubView.trailingAnchor), hostView.bottomAnchor.constraint(equalTo: uiViewSubView.bottomAnchor) ]) // 绑定Hosting Controller的生命周期,避免视图异常 addChild(host) host.didMove(toParent: self) } }
关键修改说明
- 修正视图实例:将
ContentView()改为ContentViewChart(),确保加载目标图表视图。 - 加入主容器到视图层级:通过
view.addSubview(uiView)将蓝色容器添加到界面,并添加约束固定位置。 - 设置Host View约束:让宿主View完全填充容器子视图,给SwiftUI视图明确的显示尺寸。
- 管理子控制器生命周期:调用
addChild和didMove(toParent:),确保UIHostingController与当前VC生命周期同步。 - 移除冗余组件:去掉不必要的
NavigationView,避免占用容器空间影响图表显示。
内容的提问来源于stack exchange,提问作者flaneur_7508
相关产品推荐
相关产品推荐

