由枚举驱动的 SwiftUI 选择器:值未更新
Posted
技术标签:
【中文标题】由枚举驱动的 SwiftUI 选择器:值未更新【英文标题】:SwiftUI picker driven by an enum: value not updated 【发布时间】:2020-10-09 08:15:55 【问题描述】:根据 Apple 关于Picker in SwiftUI using an Enum 的文档,如果枚举除了CaseIterable
之外还符合Identifiable
协议,则遍历所有案例的选择器应该本地更新绑定变量。
我测试了它,它没有按预期工作。
enum Flavor: String, CaseIterable, Identifiable
case chocolate
case vanilla
case strawberry
var id: String self.rawValue
struct EnumView: View
@State private var selectedFlavor = Flavor.chocolate
var body: some View
VStack
Picker("Flavor", selection: $selectedFlavor)
ForEach(Flavor.allCases) flavor in
Text(flavor.rawValue.capitalized)//.tag(flavor)
Text("Selected flavor: \(selectedFlavor.rawValue)")
但是,如果我为每个视图传递一个tag
,它就会起作用。
这里发生了什么?苹果文档有错吗? selectedFlavor
变量需要 Flavor
类型的值,但选择器中使用的 id 实际上是 String
。
谢谢。
【问题讨论】:
【参考方案1】:要使Picker
正常工作,需要识别其元素。
请注意,selectedFlavor
变量的类型为 Flavor
。这意味着 Picker 中的选项应该被标识为 Flavors(而不是 Strings)。
但是,在您的代码中,您的 id
是 String
类型:
var id: String self.rawValue
您可以:
提供tag
(Flavor
类型):
Text(flavor.rawValue.capitalized)
.tag(flavor)
通过提供 Flavor
类型的自定义 id
使 Flavor
与 Identifiable
一致:
var id: Flavor self
在ForEach
中明确指定id
参数(Flavor
类型):
ForEach(Flavor.allCases, id: \.self) ...
将selectedFlavor
更改为字符串:
@State private var selectedFlavor = Flavor.chocolate.rawValue
【讨论】:
但是当元素符合 Identifiable 时,ForEach 应该使用每个选项的 id 自动为选择器中的选择视图分配一个标签。我不明白为什么选择器不会自动将用作标签的字符串 id 转换为使用此 id 的 rawValue 作为标签的枚举。 @alpennec 我添加了更详细的解释。我希望现在更清楚了。 感谢您的解释。列出所有可能的选项是件好事。如果我理解得很好,当传递给 ForEach 循环的项目符合 Identifiable 时(即我们不需要告诉要使用的 id),为 ForEach 循环中的每个视图生成的标签是 id? So if we have an id of type String for an Enum, then the tag for the view is a String, and when the picker selects an item, it selects a String whereas the expected value for the selection is an Enum.对吗? @alpennec 是的,没错。基本上问题是关于使用字符串标记值并期望将 Flavor 作为所选项目。【参考方案2】:这是对@pawello2222 已经很棒的答案的补充。
只是为了澄清使用以下代码使枚举符合 Identifiable 的解决方案可以正确标记 UI 选择器,而无需在选择器代码中明确声明它:
var id: Flavor self
官方Apple documentation for the swiftUI picker 说使用var id: String self.rawValue
对枚举进行标识,但使用示例代码的其余部分无法按预期工作。
【讨论】:
以上是关于由枚举驱动的 SwiftUI 选择器:值未更新的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI - 使用带有枚举的选择器和提供的值并返回正确的 tag()