You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在UIViewRepresentable中嵌入SwiftUI View:应在何处构建及刷新视图?

在UIViewRepresentable中嵌入SwiftUI View:应在何处构建及刷新视图?

我之前做混合开发的时候也纠结过这个问题,后来摸清楚了——核心就是靠UIHostingController这个“桥梁”,它能把SwiftUI View完美包装成UIKit能识别的控制器视图。下面给你说说具体的构建和刷新时机:

一、视图构建:放在makeUIView(context:)里

这个方法是UIViewRepresentable用来初始化UIKit视图的地方,只会调用一次,刚好适合创建UIHostingController并完成布局:

struct HostingWrapperView: UIViewRepresentable {
    @ViewBuilder let swiftUIView: () -> some View
    
    func makeUIView(context: Context) -> UIView {
        // 创建宿主控制器,传入要嵌入的SwiftUI View
        let hostingController = UIHostingController(rootView: swiftUIView())
        let containerView = UIView()
        
        // 把宿主视图添加到容器,设置自动布局占满整个容器
        hostingController.view.translatesAutoresizingMaskIntoConstraints = false
        containerView.addSubview(hostingController.view)
        
        NSLayoutConstraint.activate([
            hostingController.view.topAnchor.constraint(equalTo: containerView.topAnchor),
            hostingController.view.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
            hostingController.view.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
            hostingController.view.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)
        ])
        
        return containerView
    }
}

二、视图刷新:放在updateUIView(_:context:)里

当外部的状态(比如绑定的@State、@Binding值变化,或者UIViewRepresentable的属性更新)时,SwiftUI会自动调用updateUIView,这时候我们只需要更新UIHostingController的rootView就行:

func updateUIView(_ uiView: UIView, context: Context) {
    // 从容器视图里找到对应的HostingController
    guard let hostingController = uiView.subviews.first?.next as? UIHostingController<some View> else {
        return
    }
    // 刷新根视图,触发SwiftUI View的更新
    hostingController.rootView = swiftUIView()
}

踩过的坑要提醒你

  • 绝对别在updateUIView里重新创建UIHostingController!每次创建都会销毁旧的控制器,不仅浪费性能,还可能导致视图状态丢失,比如输入框的内容、滚动位置这些。
  • 要让SwiftUI能检测到状态变化,一定要把影响SwiftUI View的参数都作为HostingWrapperView的属性——比如你要传个用户名进去,就定义let userName: String,这样当userName变了,updateUIView才会被调用。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 13:59:29