SwiftUI中用ForEach实现NavigationLink跳转详情页遇问题求助
我正在跟随Kodeco的SwiftUI与Combine教程,该教程通过API获取数据并在列表中展示,但教程未说明如何从列表跳转到详情页。我尝试实现此功能时无法适配现有代码,出现编译错误。
现有代码
List视图代码
var body: some View { NavigationView { List { characterSection } .navigationTitle("Characters") } }
Character Section代码
var characterSection: some View { Section { ForEach(viewModel.dataSource, content: CharacterListRowView.init(viewModel:)) } }
尝试的错误代码
ForEach(viewModel.dataSource, content: CharacterListRowView.init(viewModel:)) { item in NavigationLink(destination: viewModel.characterDetailView) { } }
错误信息
Generic parameter 'ID' could not be inferred,
Incorrect argument label in call (have ':content::', expected '_:id:content:')
Trailing closure passed to parameter of type 'KeyPath<Array.Element, ID>' that does not accept a closure
行视图模型代码
import Foundation import SwiftUI struct CharacterRowViewModel: Identifiable { private let item: CharacterListResponse var id: Int { return item.char_id } var title: String { guard let title = item.name?.description else { return "" } return title } init(item: CharacterListResponse) { self.item = item } }
解决方案
你的错误根源是错误使用了ForEach的构造器——你试图同时给ForEach传content参数和尾随闭包,但ForEach的构造器不支持这种写法。以下是两种可行的修复方式:
方法1:修改CharacterSection,将NavigationLink包裹在行视图外
直接调整characterSection的代码,把原行视图作为NavigationLink的标签,嵌套在ForEach的闭包中:
var characterSection: some View { Section { ForEach(viewModel.dataSource) { rowViewModel in NavigationLink( // 这里根据你的详情页需求传入对应ViewModel,示例如下 destination: CharacterDetailView(viewModel: CharacterDetailViewModel(character: rowViewModel.item)) ) { CharacterListRowView(viewModel: rowViewModel) } } } }
方法2:确认dataSource的元素类型
从行视图模型代码看,CharacterRowViewModel已经实现了Identifiable协议,因此需确保viewModel.dataSource是[CharacterRowViewModel]类型——如果它存储的是原始的CharacterListResponse对象,需要先转换为CharacterRowViewModel实例后再遍历。
关键说明
你原来的写法中,ForEach已经通过content:参数指定了行视图的生成方式,后续又添加的尾随闭包属于无效传参,这才触发了编译器报错。正确的逻辑是:将每个列表项包装为NavigationLink,点击时跳转到对应的详情页。
内容的提问来源于stack exchange,提问作者jbeu425

