SwiftUI使用searchable后NavigationLink自动弹出退回问题如何解决
问题原因
- 核心触发逻辑是:你在搜索文本的Binding setter中直接修改了
@FetchRequest的nsPredicate,导致搜索时FetchedResults的数据源会实时随搜索词变化。当你点击搜索结果中的NavigationLink跳转时,系统会自动失活搜索框、收起搜索键盘,此时如果数据源因为搜索状态变化发生了重排/刷新,你点击的对应item在原始ForEach的数据源中被临时移除,NavigationLink的上下文失效,就会自动触发pop操作退回到列表页。
修复方案
方案1:分离原始数据源和搜索过滤结果(兼容性最好,推荐)
不要直接修改FetchRequest的predicate,而是基于原始FetchRequest结果做本地过滤,避免数据源随搜索状态频繁变更:
struct NavTest: View { @Environment(\.managedObjectContext) private var viewContext @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Title.restid, ascending: false)]) var coreList: FetchedResults<Title> @State private var searchText = "" // 计算属性返回过滤后的结果,不修改原始FetchRequest var filteredList: [Title] { if searchText.isEmpty { return Array(coreList) } else { return coreList.filter { $0.title?.localizedCaseInsensitiveContains(searchText) ?? false } } } var body: some View { NavigationView{ List{ ForEach(filteredList, id: \.self) { item in NavigationLink(destination: PlayerView(item.title!)){ Text(item.title!) } } } // 直接绑定searchText,不需要自定义Binding .searchable(text: $searchText) } } }
方案2:适配iOS16+ 改用NavigationStack
如果你的App最低支持iOS16,替换废弃的NavigationView为NavigationStack也可以解决这个问题,新的导航栈对搜索状态下的NavigationLink上下文处理更稳定。
额外提示:如果你的Title实体的title属性可能为空,建议做好空值判断,不要直接用强制解包!,避免异常崩溃。
内容的提问来源于stack exchange,提问作者user14642906
相关产品推荐
相关产品推荐

