SwiftUI 中的 Picker 适用于 ForEach 的一个版本,但不适用于另一个版本 - 错误或预期行为?

Posted

技术标签:

【中文标题】SwiftUI 中的 Picker 适用于 ForEach 的一个版本,但不适用于另一个版本 - 错误或预期行为?【英文标题】:Picker in SwiftUI works with one version of ForEach, but not the other - a bug, or expected behavior? 【发布时间】:2020-07-16 15:33:33 【问题描述】:

看哪两个拾取器。第一个,当未注释(和第二个注释)不起作用时——当我改变房间时, Text() 没有得到更新。但是这里显示的代码,带有第二个 Picker,可以。

唯一的区别在于内容闭包。为什么我如何创建内容会影响绑定?这是错误还是预期行为?

struct ContentView: View 
var rooms = ["Kitchen", "Dining Room", "Living Room", "Bathroom"]

@State private var selectedRoomIndex = 0

var body: some View 
    VStack 
        /* Doesn't work :-(
        Picker(selection: $selectedRoomIndex, label: Text("Room: ")) 
          ForEach(rooms, id: \.self) room in
              Text(room)
        
          
        
        */

        /* This works, huzzah! But why? */
        Picker(selection: $selectedRoomIndex, label: Text("Room: ")) 
            ForEach(0 ..< rooms.count)
                Text(rooms[$0])
                
            
        
        
        Text("Chosen room: \(rooms[selectedRoomIndex])")
        Spacer()
    

【问题讨论】:

【参考方案1】:

Picker 选择和内容ForEach 数据必须是同一类型,这就是为什么第二个变体起作用的原因 - 选择是 Int 并且 ForEach 元素是 Int,所以可能第一个变体工作应该如下所示

使用 Xcode 12 / ios 14 测试

@State private var selectedRoom: String = "Kitchen"

var body: some View 
    VStack 
        Picker(selection: $selectedRoom, label: Text("Room: ")) 
            ForEach(rooms, id: \.self) room in
                Text(room)

            
        

        Text("Chosen room: \(selectedRoom)")
        Spacer()
    

【讨论】:

以上是关于SwiftUI 中的 Picker 适用于 ForEach 的一个版本,但不适用于另一个版本 - 错误或预期行为?的主要内容,如果未能解决你的问题,请参考以下文章

iOS 15 SwiftUI 3 Picker 绑定在更改@State 值后不起作用

禁用 SwiftUI SegmentedPickerStyle Picker 中的段?

SwiftUI Picker 在同一视图中更改第二个状态变量

SwiftUI 中的一排 Picker ***,为啥拖动滚动区域从屏幕上的 Picker 控件偏移?

SwiftUI for MacOS 中的多行 TextField/TextEditor 表单

SwiftUI Picker 填充问题 - 选择器中的 ForEach 循环不填充