选择新选项时未调用 SwiftUI Picker OnChange

SwiftUI Picker OnChange not being called when new option is being selected

SeasonData 是 Season 类型的对象数组

userData 持有 2 [INT] lastUsedSeason -> 引用访问的 SeasonData 的最后 3 个数组位置 [3,1,0]

arrayPosition 保持 [0,1,2]。

这些是从文件加载的。

此选择器的显示和选择工作正常。但是我不知道如何在更改选择时触发 onChange。

    struct UserData: Codable {
      var lastUsedSeason: [Int]
      var arrayPosition: [Int]
    
     mutating func addLastUsedSeason(index: Int) {
        if (lastUsedSeason.count > 3){
          lastUsedSeason.insert(index, at: 0)
          lastUsedSeason.remove(at: 2)
        }
      }
    }

    @main
    struct SandStats_New_App: App {
      @StateObject private var modelData = ModelData()
      
      @State private var showSeason = false
      
      
        var body: some Scene {
            WindowGroup {
              ContentView(seasonSelected: $showSeason)
                .environmentObject(modelData)
                .frame(minWidth: 700, minHeight: 300, alignment: .topLeading)
                .background(Color.red)
            }
            .commands {
              SandStatCommands(addSeasonButton: $showSeason, modelData: modelData)
            }
        }
    }

struct SandStatCommands: Commands {
  var modelData : ModelData
  @Binding var addSeasonButton: Bool
  @State var seasonSelection: Int = 0

  var body: some Commands {
    
      CommandMenu("Season"){
        
        Button("Add Season"){
          addSeasonButton = true
        }
        Picker(selection: $seasonSelection, label: Text("Selected Season")){
          ForEach(modelData.userData.arrayPosition, id:\.self) { index in
            Text(modelData.seasons[modelData.userData.getLastUsedSeason(index1: index)].seasonName()).tag(index)
          }
        }.onChange(of: seasonSelection, perform:  { value in
          print(value)
        })
        
        Button("save Index"){
          saveData(for: modelData.userData, to: "userData")
        }
      }
      
    }
}

要使 seasonSelectionPicker 中工作,请将 .tag() 添加到 Text(...) 并确保它与 seasonSelection 的类型相同,例如(假设 index 是 Int 类型):

注意:这适用于 macCatalyst,仅适用于 macOS,请参阅编辑。

Picker(selection: $seasonSelection, label: Text("Selected Season")){
  ForEach(userData.userData.lastUsedSeason, id:\.self) { index in
    Text(seasonData.seasons[index].seasonName()).tag(index)  // <-- here
  }
}
 .onChange(of: seasonSelection, perform:  { _ in
  seasonData.seasons[0].testPrint()
 })

编辑:示例代码显示了如何在 .onReceive() 中仅在 macOS 上使用 tagseasonSelection,以及如何在 macCatalyst 中使用 .onChange()

import SwiftUI
import Combine

@main
struct TestMacApp: App {
    var body: some Scene {
        WindowGroup {
            Text("demo").frame(width: 480.0, height: 320.0)
        }
        .commands {
            SandStatCommands()
        }
    }
}

struct SandStatCommands: Commands {
    @State var seasons = ["Spring","summer","autumn","winter"]  // array of values
    @State var seasonSelection: Int = 0  // <-- here initial selection
    
    var body: some Commands {
        CommandMenu("Season"){
            Button("Add Season"){
                seasons.append(String(UUID().uuidString.prefix(6))) // for demo, add a random name
            }
            Picker(selection: $seasonSelection, label: Text("Selected Season")){
                ForEach(0..<seasons.count, id:\.self) { index in
                    Text(seasons[index]).tag(index)  // <-- here tag
                }
            }
           // .onChange(of: seasonSelection) { value in
           //     print("---> seasonSelection value: \(value)")
           //  }
          .onReceive(Just(seasonSelection)) { value in
             print("---> seasonSelection value: \(value)")
          }
        }
    }
}