我正在尝试使Picker能够根据先前Picker的选择进行动态更新。为了实现这一点,我使用了多维数组。不幸的是,这似乎使我的ForEach循环感到困惑,并且我在日志中注意到以下消息:
ForEach<Range<Int>, Int, Text> count (3) != its initial count (5).
ForEach(:content:)should only be used for *constant* data. Instead conform data to
可识别or use
ForEach(:id:content:)and provide an explicit
id {{1} }
这有点道理,我猜正在发生的事情是我正在将它传递给一个数组,并且它一直在引用它,因此就它而言,每当我传递给另一个数组时,它就一直在不断变化。我相信解决此问题的方法是使用可以传递给ForEach的id参数,尽管我不确定这是否可以解决这个问题,也不确定我会使用什么。另一个解决方案是以某种方式销毁Picker并重新创建它?有任何想法吗?
我的代码如下。如果运行它,您会注意到在第一个选择器周围移动可能会导致超出范围的异常。
!
答案 0 :(得分:1)
我不愿回答自己的问题,但是花了一些时间后,我认为有必要总结一下我的发现,以防对他人有所帮助。总而言之,我试图根据第一个选择器的选择来设置第二个选择器。
如果按原样运行我粘贴的代码,则会超出范围。仅当我设置@State private var dimensionSelection = 1
并且第二个数组大于第一个数组时,才是这种情况。如果从较小的数组开始,可以通过设置@State private var dimensionSelection = 0
来观察。有几种解决方法。
String
数组。这是上面fuzz提出的解决方案。这超出了界限数组异常。但就我而言,我需要在ForEach参数中指定id参数。Identifiable
,只要您的字符串都不同(在我的琐碎示例中就可以使用)。这是gujci提出的解决方案,他提出的解决方案看上去比我的解决方案优雅得多,因此,我鼓励您看看。请注意,这在我自己的示例中有效。我怀疑这可能是由于我们如何以不同的方式构建阵列。但是,一旦您克服了这些问题,它仍然无法工作,您将遇到一个问题,该问题似乎是Picker不断添加新元素的某种错误。我的印象是要解决此问题,每次都必须销毁Picker,但是由于我仍在学习Swift和SwiftUI,因此我并没有绕过这一步。
答案 1 :(得分:0)
因此,您要根据Apple的文档确保您所提到的数组元素为Identifiable
。
然后您将要像这样使用ForEach
:
struct Dimension: Identifiable {
let id: Int
let name: String
}
var temperatureUnits = [
Dimension(id: 0, name: "Celsius"),
Dimension(id: 1, name: "Fahrenheit"),
Dimension(id: 2, name: "Kelvin")
]
ForEach(temperatureUnits) { dimension in
Text(dimension.name)
}