使用不同的数组动态更改选择器中的选项

时间:2019-10-14 02:34:06

标签: swift swiftui

我正在尝试使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并重新创建它?有任何想法吗?

我的代码如下。如果运行它,您会注意到在第一个选择器周围移动可能会导致超出范围的异常。

!

2 个答案:

答案 0 :(得分:1)

我不愿回答自己的问题,但是花了一些时间后,我认为有必要总结一下我的发现,以防对他人有所帮助。总而言之,我试图根据第一个选择器的选择来设置第二个选择器。

如果按原样运行我粘贴的代码,则会超出范围。仅当我设置@State private var dimensionSelection = 1并且第二个数组大于第一个数组时,才是这种情况。如果从较小的数组开始,可以通过设置@State private var dimensionSelection = 0来观察。有几种解决方法。

  1. 总是从最小的数组开始(不好)
  2. 使用实现Identifiable的对象数组代替使用String数组。这是上面fuzz提出的解决方案。这超出了界限数组异常。但就我而言,我需要在ForEach参数中指定id参数。
  3. 扩展字符串以实现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)
}