根据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)")
}
}
}
但是,如果我为每个视图传递一个tag
,它就会起作用。
这是怎么回事? Apple文档是否有误? selectedFlavor
变量的值为Flavor
类型,但选择器中使用的ID实际上是String
。
谢谢。
答案 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 }
来枚举枚举,并且在其余示例代码中无法正常工作。