在SwiftUI中,ForEach要求传入的数据必须是随机访问集合(Array、Range、Slice 等)。
ForEach结构:
public struct ForEach<Data, ID, Content> where Data : RandomAccessCollection, ID : Hashable {
public var data: Data
public var content: (Data.Element) -> Content
}
如果传入的数据只是一个Sequence(序列),那么就会缺失访问下标的能力。
编译器报错:
Generic struct 'ForEach' requires that 'EnumeratedSequence<[(String, String)]>' conform to 'RandomAccessCollection'
解决方案
方案1:转换成Array
将Sequence(序列)转换成Array:
ForEach(Array(tabs.enumerated()), id: \.offset) { index, tab in
let (image, text) = tab
SingleTabView(HomeImage: image, HomeText: text)
}
Array(tabs.enumerated()) 生成 [ (offset: Int, element: (String, String)) ]
Array 符合 RandomAccessCollection(随机访问集合),可以被 ForEach 使用。
方案二:直接使用索引访问原数组
ForEach(tabs.indices, id: \.self) { index in
let (image, text) = tabs[index]
SingleTabView(HomeImage: image, HomeText: text)
}
tabs.indices 是 Range<Int>,也是 RandomAccessCollection。
不需要用 enumerated(),写法更简单。
总结
避免在 ForEach 中使用 Sequence(序列),尤其是直接使用 enumerated(),要么 Array() 包裹,要么用索引。