SwiftUI List报错:[Int]无法转为Range<Int>,为何oceans可正常使用?
SwiftUI List 数组渲染报错问题解答
问题场景
以下是我的代码:
struct ContentView: View { // an array of oceans private var oceans = [ Ocean(name: "Pacific"), Ocean(name: "Atlantic"), Ocean(name: "Indian"), Ocean(name: "Southern"), Ocean(name: "Arctic") ] // an array of numbers private var nums = [1, 2, 3, 4, 5] var body: some View { VStack{ List(oceans) { ocean in Text("\(ocean.name)") } List(nums) { num in // error appears here } }//VStack }
尝试调用List(nums) { num in }时出现报错:
Cannot convert value of type '[Int]' to expected argument type 'Range
'
疑问:为何使用oceans数组时可正常运行,使用nums数组时却出现该问题?
原因分析
核心区别在于元素是否遵循Identifiable协议:
- 你的
Ocean结构体必然遵循了Identifiable协议(通常是添加了id属性,比如let id = UUID()),SwiftUI的List提供了专门的初始化方法,可直接接收遵循该协议的元素数组,系统能通过id唯一标识每个元素。 Int是系统基础类型,默认没有遵循Identifiable。此时直接传入[Int],编译器会匹配到另一个接收Range<Int>参数的List初始化方法(比如List(0..<5) { ... }),所以才会出现类型不匹配的报错。
解决方法
方法一:手动指定元素标识
给List添加id参数,用\.self作为Int元素的唯一标识(因为数组里的Int值都是唯一的):
List(nums, id: \.self) { num in Text("\(num)") }
方法二:包装元素为遵循Identifiable的类型
将Int包装成自定义结构体,让其遵循Identifiable:
struct NumberItem: Identifiable { let id = UUID() let value: Int } // 修改nums数组的类型 private var nums = [ NumberItem(value: 1), NumberItem(value: 2), NumberItem(value: 3), NumberItem(value: 4), NumberItem(value: 5) ] // 之后即可像oceans那样使用List List(nums) { item in Text("\(item.value)") }
内容的提问来源于stack exchange,提问作者Elaine Chen
相关产品推荐
相关产品推荐

