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

SwiftUI中修改事件后导航链接自动退出详情页问题求助

问题分析与解决方案

你的问题核心是ForEach内部的条件渲染导致视图身份不稳定,当修改详情页的事件属性后,原列表中对应项的显示条件发生变化,触发视图树结构变更,导致Navigation自动弹出详情页。

修复代码

首先重构搜索过滤逻辑,将过滤后的数组单独计算,再基于这个稳定的数据源构建列表:

import SwiftUI

struct SearchBar: View {
    @Binding var dates: [DatesInfo]
    @State private var searchText = ""

    // 提前计算过滤后的事件数组
    private var filteredDates: [DatesInfo] {
        guard !searchText.isEmpty else { return dates }
        return dates.filter {
            $0.title.lowercased().contains(searchText.lowercased())
        }
    }

    var body: some View {
        List {
            // 遍历过滤后的数组,通过id匹配原数组的绑定
            ForEach(filteredDates, id: \.id) { filteredDate in
                if let dateIndex = dates.firstIndex(where: { $0.id == filteredDate.id }) {
                    NavigationLink {
                        DetailView(thisDate: $dates[dateIndex])
                    } label: {
                        Text(filteredDate.title)
                    }
                }
            }
        }
    }
}

关键原因说明

  1. 原代码的问题:你在ForEach内部直接对每个item做条件判断,决定是否显示NavigationLink。当修改详情页的事件title后,该item可能不再满足当前搜索过滤条件,导致对应的NavigationLink被从视图树中移除——此时用户正处于这个链接对应的详情页,视图结构的突变会触发NavigationStack自动弹出页面。
  2. 修复逻辑:通过提前计算filteredDates,让ForEach的数据源是稳定的过滤结果,避免在遍历过程中动态添加/移除视图。同时通过id匹配原数组的绑定,确保修改操作直接作用于原始数据源,且列表视图的身份不会因为过滤条件变化而混乱。

额外注意事项

确保DatesInfo的id是不可变且唯一的(比如初始化时生成UUID()),不要用title这类会被修改的属性作为id,否则即使使用id: \.id,也会因为id变化导致视图身份失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 14:30:12