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

SwiftUI中ChatView无法显示,始终出现ProgressView问题求助

问题原因与解决方案

你的问题出在fullScreenCover的isPresented绑定和chatUser的状态更新不同步:当你在sheet的回调里设置chatUser后立刻切换shouldNavigateToChatView,SwiftUI可能还没完成chatUser的状态更新,fullScreenCover就已经开始渲染,导致第一个if let分支没命中,最终显示ProgressView。

修复方案:改用item绑定替代isPresented

用fullScreenCover(item:)绑定可选的导航目标,SwiftUI会自动检测可选值的变化,确保状态同步后再渲染对应视图。

步骤1:定义导航目标枚举

先创建一个枚举来区分两种导航场景,同时实现Identifiable协议(item绑定要求遵循该协议):

enum ChatNavigationTarget: Identifiable {
    case user(User)
    case chat(ChatModel)
    
    var id: String {
        switch self {
        case .user(let user):
            return user.id
        case .chat(let chat):
            return chat.id // 确保ChatModel有id属性
        }
    }
}

步骤2:替换原有状态变量

把原来的chatUser、chatForView、shouldNavigateToChatView替换成一个枚举类型的状态变量:

@State private var navigationTarget: ChatNavigationTarget?

步骤3:修改触发导航的逻辑

  • 聊天列表单元格点击事件:
ChatListCell(chat: chat)
    .onTapGesture {
        navigationTarget = .chat(chat)
    }
  • 新建聊天选择用户后的回调:
ChatCreationView(didSelectUser: { user in
    print("did select user \(user)")
    navigationTarget = .user(user)
})

步骤4:更新fullScreenCover绑定

替换原来的isPresented绑定为item绑定,通过switch匹配不同场景:

.fullScreenCover(item: $navigationTarget) { target in
    switch target {
    case .user(let user):
        ChatView(oppUser: user)
    case .chat(let chat):
        ChatView(chat: chat)
    }
}

完整修改后的代码

enum ChatNavigationTarget: Identifiable {
    case user(User)
    case chat(ChatModel)
    
    var id: String {
        switch self {
        case .user(let user):
            return user.id
        case .chat(let chat):
            return chat.id
        }
    }
}

struct ChatListView: View {
    
    @State private var shouldShowChatCreationScreen = false
    @State private var navigationTarget: ChatNavigationTarget?
    @ObservedObject private var viewModel = ChatListViewModel()
    
    var body: some View {
        NavigationView {
            ScrollView {
                ForEach(viewModel.chats) { chat in
                    ChatListCell(chat: chat)
                        .onTapGesture {
                            navigationTarget = .chat(chat)
                        }
                }
            }
            .navigationTitle("Chats")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(action: {
                        shouldShowChatCreationScreen.toggle()
                    }) {
                        Image(systemName: "square.and.pencil")
                    }
                }
            }
            .sheet(isPresented: $shouldShowChatCreationScreen) {
                ChatCreationView(didSelectUser: { user in
                    print("did select user \(user)")
                    navigationTarget = .user(user)
                })
            }
            .fullScreenCover(item: $navigationTarget) { target in
                switch target {
                case .user(let user):
                    ChatView(oppUser: user)
                case .chat(let chat):
                    ChatView(chat: chat)
                }
            }
        }
    }
}

这样修改后,状态更新会被SwiftUI正确捕获,再也不会出现状态不同步导致的ProgressView问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:35:55