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

CoreData实体在SwiftUI视图间传递异常:点击任意行均显示首个实体

解决SwiftUI详情页显示错误Trip实体的问题

问题原因

你当前的实现里,所有TripRow都绑定了同一个viewRouter.isShowingDetailTripView布尔状态。当点击任意行触发这个状态变为true时,所有TripRow的fullScreenCover都会尝试渲染对应的DetailTripView,但SwiftUI只会显示其中一个(通常是列表中第一个被渲染的Trip对应的详情页),导致无论点击哪一行,详情页都显示同一个错误的Trip实体。

解决方案

改用fullScreenCover(item:)绑定方式,通过在ViewRouter中存储选中的Trip实体来控制详情页展示,具体步骤如下:

1. 修改ViewRouter

把原来的布尔状态替换为可选的Trip对象,用来存储用户选中的Trip:

class ViewRouter: ObservableObject {
    @Published var selectedTrip: Trip? // 替换原有的isShowingDetailTripView
}

2. 更新TripRow代码

使用item绑定替代isPresented,点击时将当前Trip赋值给ViewRouter的selectedTrip:

struct TripRow: View {
    @EnvironmentObject var viewRouter: ViewRouter
    var trip: Trip
    var body: some View {
        // ... 你的TripRow原有内容
        .fullScreenCover(item: $viewRouter.selectedTrip) { selectedTrip in
            DetailTripView(trip: selectedTrip)
                .environmentObject(viewRouter)
        }
        .onTapGesture {
            viewRouter.selectedTrip = trip // 赋值当前选中的Trip
        }
    }
}

3. 让Trip实体遵循Identifiable协议

CoreData实体可通过扩展实现Identifiable,确保fullScreenCover(item:)能正确识别唯一实体:

extension Trip: Identifiable {}

4. 清理TripView无用代码

删除TripView中未使用的@State var tappedTrip = 0:

struct TripView: View {
    @EnvironmentObject var viewRouter: ViewRouter
    @FetchRequest(entity: Trip.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Trip.startDate, ascending: true)], predicate: nil, animation: .linear) var trips: FetchedResults<Trip>
    
    var body: some View {
        VStack(spacing: 20) {
            ForEach(trips, id: \.self) { trip in
                TripRow(trip: trip)
                    .environmentObject(viewRouter)
            }
        }
    }
}

原理说明

fullScreenCover(item:)会根据绑定的可选对象是否非nil来决定是否展示详情页,且对象更新时会自动传递对应实体给详情页。这种方式确保每次点击不同的TripRow时,详情页显示的都是用户选中的那个Trip实体,避免了多个fullScreenCover共用同一个布尔开关导致的冲突问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 12:40:22