SwiftUI点击不同元素跳转新视图却显示旧数据问题求助
问题排查与修复方案
核心问题分析
FeedView中
fullScreenCover用法错误:
在ForEach内部为每个Tweet绑定同一个showNewCommentView布尔状态,导致SwiftUI无法正确区分不同Tweet对应的CommentView实例。关闭视图后再次点击其他Tweet时,系统可能复用了旧的视图实例,进而显示旧数据。CommentView数据源笔误:
ViewModel中发布的评论数组是comments,但视图里遍历的却是viewModel.tweets,这会导致显示内容与实际获取的评论数据不匹配。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
相关产品推荐
相关产品推荐

