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

SwiftUI点击不同元素跳转新视图却显示旧数据问题求助

问题排查与修复方案

核心问题分析

  1. FeedView中fullScreenCover用法错误:
    在ForEach内部为每个Tweet绑定同一个showNewCommentView布尔状态,导致SwiftUI无法正确区分不同Tweet对应的CommentView实例。关闭视图后再次点击其他Tweet时,系统可能复用了旧的视图实例,进而显示旧数据。

  2. CommentView数据源笔误:
    ViewModel中发布的评论数组是comments,但视图里遍历的却是viewModel.tweets,这会导致显示内容与实际获取的评论数据不匹配。

  3. CommentView未初始化必要状态:
    selectedTweet未在初始化时赋值,且缺少showNewCommentView状态变量,会引发运行时异常,同时影响嵌套跳转逻辑。


修复步骤

1. 修正FeedView的全屏跳转逻辑

将布尔状态改为可选Tweet变量控制跳转,并把fullScreenCover移到ForEach外部,确保每个点击事件正确传递对应的Tweet实例:

struct FeedView: View {
    @StateObject var viewModel = FeedViewModel()
    @State private var selectedTweet: Tweet?
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        ZStack(alignment: .bottomTrailing){
            ScrollView {
                LazyVStack{
                    ForEach(viewModel.tweets){ tweet in
                        Button{
                            selectedTweet = tweet
                        } label: {
                            TweetRowView(tweet: tweet, hasDivider: true)
                                .padding()
                        }
                    }
                }
            }
            .fullScreenCover(item: $selectedTweet) { tweet in
                CommentView(tweet: tweet)
            }
        }
    }
}

2. 修复CommentView的数据源与状态问题

修正遍历的数据源为viewModel.comments,补全必要状态变量,确保初始化逻辑正确:

struct CommentView: View {
    @StateObject var viewModel = CommentViewModel()
    @Environment(\.presentationMode) var presentationMode
    let tweet: Tweet
    @State private var selectedTweet: Tweet?
    @State private var showNewCommentView = false
    
    init(tweet: Tweet){
        self.tweet = tweet
    }
    
    var body: some View {
        VStack(alignment: .leading, spacing: 0){
            ZStack(alignment: .bottomTrailing){
                ScrollView {
                    // 注意:如果Comment与Tweet结构不同,需替换为对应的CommentRowView
                    ForEach(viewModel.comments) { comment in
                        Button{
                            selectedTweet = comment.tweet // 根据你的数据结构调整
                            showNewCommentView.toggle()
                        } label: {
                            TweetRowView(tweet: comment.tweet, hasDivider: true)
                                .padding()
                        }
                    }
                    .fullScreenCover(item: $selectedTweet) { tweet in
                        CommentView(tweet: tweet)
                    }
                }
                
                Button {
                    presentationMode.wrappedValue.dismiss()
                } label: {
                    Image(systemName: "arrow.down")
                }
            }
        }
        .onAppear{
            viewModel.getComments(withTweet: tweet)
        }
    }
}

3. 优化ViewModel的数据更新逻辑

在获取新评论前清空旧数据,确保UI更新在主线程执行:

class CommentViewModel: ObservableObject{
    @Published var comments = [Comment]()
    let service = TweetService()

    func getComments(withTweet tweet: Tweet){
        comments.removeAll() // 清空旧数据避免残留
        service.getComments(tweet: tweet) { comments in
            DispatchQueue.main.async {
                self.comments = comments
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 15:25:35