选择新选项时未调用 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")
}
}
}
}
要使 seasonSelection
在 Picker
中工作,请将 .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 上使用 tag
和 seasonSelection
,以及如何在 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)")
}
}
}
}
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")
}
}
}
}
要使 seasonSelection
在 Picker
中工作,请将 .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 上使用 tag
和 seasonSelection
,以及如何在 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)")
}
}
}
}