SwiftUI 中可选数据类型的选择器?

Sen*_*ful 31 swiftui

通常我可以在 SwiftUI 中显示这样的项目列表:

enum Fruit {
    case apple
    case orange
    case banana
}

struct FruitView: View {

    @State private var fruit = Fruit.apple

    var body: some View {
        Picker(selection: $fruit, label: Text("Fruit")) {
            ForEach(Fruit.allCases) { fruit in
                Text(fruit.rawValue).tag(fruit)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这非常有效,让我可以选择我想要的任何水果。但是,如果我想切换fruit为可空(又名可选),则会导致问题:

struct FruitView: View {

    @State private var fruit: Fruit?

    var body: some View {
        Picker(selection: $fruit, label: Text("Fruit")) {
            ForEach(Fruit.allCases) { fruit in
                Text(fruit.rawValue).tag(fruit)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

选择的水果名称不再显示在第一屏上,无论我选择什么选择项,它都不会更新水果值。

如何将 Picker 与可选类型一起使用?

Sen*_*ful 72

当绑定正在包装时,标记必须与确切的数据类型匹配。在这种情况下,提供给的数据类型tagFruit但 的数据类型$fruit.wrappedValueFruit?。您可以通过在tag方法中强制转换数据类型来解决此问题:

struct FruitView: View {

    @State private var fruit: Fruit?

    var body: some View {
        Picker(selection: $fruit, label: Text("Fruit")) {
            ForEach(Fruit.allCases) { fruit in
                Text(fruit.rawValue).tag(fruit as Fruit?)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

奖励:如果您想要自定义文本nil(而不是空白),并希望允许用户选择nil(注意:这里要么全部要么全无),您可以包含一个项目nil

struct FruitView: View {

    @State private var fruit: Fruit?

    var body: some View {
        Picker(selection: $fruit, label: Text("Fruit")) {
            Text("No fruit").tag(nil as Fruit?)
            ForEach(Fruit.allCases) { fruit in
                Text(fruit.rawValue).tag(fruit as Fruit?)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

不要忘记也投射nil价值。

  • 这是一个主要的警告(编译器警告在这里会很有帮助)。我至少花了几天时间来追踪这个问题。‍♂️ (7认同)
  • 此语法的几个变体:`.tag(nil as Fruit?)`、`.tag(Fruit?.none)`、`.tag(Fruit?(nil))`、`.tag(Optional<Fruit> .无)`。 (2认同)
  • 或者 `.tag(可选(水果))`。 (2认同)
  • 在 Xcode15 中,这种方法工作正常,但在调试区域中仍然有此警告:“选择器:选择“nil”无效并且没有关联的标签,这将给出未定义的结果。” (2认同)