SwiftUI使用ForEach传入多变量报Extra argument in call的解决方法
SwiftUI 内置的ForEach构造器没有支持同时传入两个数组的版本,你当前代码里给ForEach传了viewModel.cardContent、viewModel.cardnames两个入参,系统找不到匹配的初始化方法,就会抛出Extra argument in call(调用时存在多余参数)的编译错误。
另外你的现有写法就算能正常编译也有逻辑问题:闭包里只接收了一个card参数,会把同一个字符串同时传给CardView的content和name属性,根本拿不到两个数组对应位置的配对值,和预期效果不符。
根据你的业务场景,选下面任意一种方案即可:
方案1:用zip打包两个数组配对遍历
这是最适配你当前代码结构的写法,调用标准库的zip方法,可以把两个等长数组对应索引的元素组合为元组序列,直接遍历就能拿到配对的content和name值:
// 注意要把zip返回的序列转成Array,否则ForEach无法识别 ForEach(Array(zip(viewModel.cardContent, viewModel.cardnames)), id: \.0) { content, name in CardView(contentString: content, nameString: name) .frame(minWidth: 135, idealWidth: 250, maxWidth: 135, minHeight: 135, idealHeight: 250, maxHeight: 135, alignment: .center) .aspectRatio(1, contentMode: .fit) }
⚠️ 注意:使用zip时如果两个数组长度不一致,会自动以更短的数组长度为准截断,不会崩溃,但要确保业务逻辑上两个数组的元素是一一对应的。这里因为元组不支持Hashable,不能直接用\.self作为id,暂时用第一个元素\.0做id即可,如果存在content重复的情况,可以调整数据结构给每个元素加唯一标识。
方案2:遍历索引取值
也可以直接遍历数组索引,通过索引同时从两个数组里取对应位置的元素:
ForEach(viewModel.cardContent.indices, id: \.self) { index in CardView( contentString: viewModel.cardContent[index], nameString: viewModel.cardnames[index] ) .frame(minWidth: 135, idealWidth: 250, maxWidth: 135, minHeight: 135, idealHeight: 250, maxHeight: 135, alignment: .center) .aspectRatio(1, contentMode: .fit) }
⚠️ 注意:这个方案必须保证cardContent和cardnames两个数组长度完全一致,否则会出现数组越界崩溃。
你当前的数据结构里,Card结构体本身就持有一一对应的content和name数组,其实没必要在ViewModel里把两个数组拆出来单独暴露,直接基于Card本身的配对结构做遍历,能从根源上避免两个数组长度不匹配的问题。
内容的提问来源于stack exchange,提问作者readytotakeoof

