由枚举驱动的SwiftUI选择器:值未更新

时间:2020-10-09 08:15:55

标签: swiftui swiftui-picker

根据Apple关于Picker in SwiftUI using an Enum的文档,如果除Identifiable之外枚举还符合CaseIterable协议,则在所有情况下进行迭代的选择器都应本机更新绑定变量。

我对其进行了测试,但它没有按预期工作。

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)")
        }
    }
}

enter image description here

但是,如果我为每个视图传递一个tag,它就会起作用。

enter image description here

这是怎么回事? Apple文档是否有误? selectedFlavor变量的值为Flavor类型,但选择器中使用的ID实际上是String

谢谢。

2 个答案:

答案 0 :(得分:3)

要使Picker正常工作,需要确定其元素。

请注意,selectedFlavor变量的类型为Flavor。这意味着选择器中的选项应标识为风味(不是字符串)。

但是,在您的代码中,您的id的类型为String

var id: String { self.rawValue }

您可以:

  • 提供tag(类型为Flavor):
Text(flavor.rawValue.capitalized)
    .tag(flavor)
  • 通过提供类型Flavor的自定义Identifiable使id符合Flavor
var id: Flavor { self }
  • id中明确指定Flavor参数(类型为ForEach):
ForEach(Flavor.allCases, id: \.self) { ... }
  • selectedFlavor更改为字符串:
@State private var selectedFlavor = Flavor.chocolate.rawValue

答案 1 :(得分:0)

这是已经很棒的答案@ pawello2222的补充。

仅说明使用以下代码使枚举符合Identifiable的解决方案可正确标记UI选择器,而无需在选择器代码中明确声明:

func isWiFiOn() -> Bool {
        var address : String?
        var ifaddr : UnsafeMutablePointer<ifaddrs> = nil
        if getifaddrs(&ifaddr) == 0 {
            var ptr = ifaddr
            while ptr != nil {
                defer { ptr = ptr.memory.ifa_next }
                let interface = ptr.memory
                let addrFamily = interface.ifa_addr.memory.sa_family
                if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
                    if let name = String.fromCString(interface.ifa_name) where name == "awdl0" {
                        if((Int32(interface.ifa_flags) & IFF_UP) == IFF_UP) {
                            return(true)
                        }
                        else {
                            return(false)
                        }
                    }
                }
            }
            freeifaddrs(ifaddr)
        }
        return (false)
    }

官方Apple documentation for the swiftUI picker表示使用var id: Flavor { self } 来枚举枚举,并且在其余示例代码中无法正常工作。