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

SwiftUI结合UIKit导航时跨页面共享可更新数据的实现方案

完全可行:用SwiftUI ObservableObject实现跨页面数据同步

核心是借助ObservableObject结合共享数据源实例,不用回调、代理或通知就能实现UI自动同步。先给你完整实现方案,再分析你之前遇到的问题。

1. 定义可观察的任务模型与数据容器

首先把任务做成引用类型(class)并遵循ObservableObject,这样修改任务属性时能自动通知视图;再做一个全局共享的任务容器,统一管理任务列表:

// 任务状态枚举
enum TaskStatus: String, CaseIterable {
    case todo, inProgress, completed
}

// 单个任务:用class+@Published,属性变化会自动通知视图
class Task: ObservableObject, Identifiable {
    let id = UUID()
    @Published var name: String
    @Published var status: TaskStatus
    
    init(name: String, status: TaskStatus) {
        self.name = name
        self.status = status
    }
}

// 任务容器:管理所有任务,同样是ObservableObject
class TaskStore: ObservableObject {
    @Published var tasks: [Task] = []
    
    // 初始化示例数据
    init() {
        tasks = [
            Task(name: "完成SwiftUI笔记", status: .todo),
            Task(name: "整理项目文档", status: .inProgress)
        ]
    }
}

2. 在UIKit导航中传递共享实例

因为是UIKit管导航,你需要确保所有SwiftUI视图用的是同一个TaskStore实例,不能每个页面单独创建。比如:

// 全局初始化一次(或者在App/Scene初始化时创建,传递给各个页面)
let sharedTaskStore = TaskStore()

// 初始化列表页的UIHostingController
let listView = TaskListView(taskStore: sharedTaskStore)
let listHostingVC = UIHostingController(rootView: listView)

// 跳转到详情页时,传递选中的Task和共享的TaskStore
func didSelectTask(_ task: Task) {
    let detailView = TaskDetailView(task: task, taskStore: sharedTaskStore)
    let detailHostingVC = UIHostingController(rootView: detailView)
    navigationController?.pushViewController(detailHostingVC, animated: true)
}

3. SwiftUI视图实现

任务列表页

用@ObservedObject绑定共享的TaskStore,列表会自动响应任务属性的变化:

struct TaskListView: View {
    @ObservedObject var taskStore: TaskStore
    
    var body: some View {
        List(taskStore.tasks) { task in
            NavigationLink(destination: TaskDetailView(task: task, taskStore: taskStore)) {
                HStack {
                    Text(task.name)
                    Spacer()
                    Text(task.status.rawValue)
                        .foregroundColor(task.status == .completed ? .green : .orange)
                }
            }
        }
    }
}

任务详情页

直接绑定选中的Task(@ObservedObject),修改属性时,列表页会自动同步:

struct TaskDetailView: View {
    @ObservedObject var task: Task
    // 如果不需要修改列表(比如删除任务),可以不用传taskStore
    @ObservedObject var taskStore: TaskStore
    
    var body: some View {
        Form {
            TextField("任务名称", text: $task.name)
            
            Picker("状态", selection: $task.status) {
                ForEach(TaskStatus.allCases, id: \.self) { status in
                    Text(status.rawValue).tag(status)
                }
            }
        }
        .navigationTitle("任务详情")
    }
}

你之前数据更新但UI没刷新的原因

大概率是这两个问题之一:

  • 任务模型用了struct:struct是值类型,修改数组里的struct属性时,数组本身的引用没变化,@Published不会触发更新。改成class并让Task遵循ObservableObject就解决了。
  • 没有共享TaskStore实例:列表页和详情页各自创建了TaskStore,数据不是同一份,修改自然不会同步。确保所有页面用同一个实例就行。

内容的提问来源于stack exchange,提问作者Leonardo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 21:55:03