You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Xcode 13.4预览界面中SwiftUI dismiss()失效且Todo列表无法更新的问题求助

嘿,我之前在Xcode预览里也碰到过类似的坑!模拟器跑起来一切正常,可一用预览添加Todo,回到ContentView就看不到新内容,还直接卡住不动,简直头疼。咱们来一步步解决这个问题~

问题根源

Xcode预览的视图生命周期和真机/模拟器略有不同,当你在TodoEditor里刚把新Todo加到@Publishedtodos数组,立刻调用dismiss(),预览环境可能来不及同步处理状态更新和导航栈变化,结果就卡住了。另外,你的预览代码里,ContentViewTodoEditor各自新建了Todo()实例,这和实际运行时共享同一个环境对象的逻辑不符,也会导致预览里的状态没法正确同步。

修复方案

1. 给dismiss加个“缓冲”,让状态更新先完成

修改TodoEditor.swift里的Add按钮代码,用DispatchQueue.main.asyncdismiss()放到下一个主队列循环执行,确保状态更新先处理完,再返回ContentView:

Button("Add"){
    data.todos.append(newTodo)
    // 延迟执行dismiss,给预览足够时间处理状态刷新
    DispatchQueue.main.async {
        dismiss()
    }
}

2. 让预览共用同一个环境对象

当前你的两个预览各自创建Todo()实例,这不符合实际运行时的情况(实际是同一个Todo实例被整个App共享)。修改预览代码,让它们使用同一个环境对象,这样预览里的状态变化就能正确同步了:

更新ContentView的预览:

struct ContentView_Previews: PreviewProvider {
    // 创建一个共享的Todo实例,供所有预览使用
    static let sharedTodoData = Todo()
    
    static var previews: some View {
        NavigationView{
            ContentView()
                .environmentObject(sharedTodoData)
        }
    }
}

更新TodoEditor的预览:

struct TodoEditor_Previews: PreviewProvider {
    // 复用ContentView预览里的共享实例
    static let sharedTodoData = ContentView_Previews.sharedTodoData
    
    static var previews: some View {
        NavigationView{
            TodoEditor(newTodo: Task(taskContent: "Hello", isCompleted:false))
                .environmentObject(sharedTodoData)
        }
    }
}

为什么这招管用?

  • 延迟dismiss()让SwiftUI有足够时间处理@Published数组的更新,触发ContentView刷新后再执行导航返回,避免了预览里的刷新冲突。
  • 共用环境对象实例让预览的状态逻辑和实际运行时保持一致,添加Todo后ContentView能正确接收到更新,自然就能显示新内容了。

这样调整完,你再试试Xcode预览,应该就能正常添加Todo并看到更新后的列表,不会再卡住啦!

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

火山引擎 最新活动