SwiftUI2, Picker .onChange 触发两次需要更改之前和之后的值

问题描述

我遇到了类似于以下帖子 .onReceive firing twice 的问题。

我有一个触发 .onChange 两次的选择器。我正在为选择器使用模型数据环境对象。

有没有办法让我获得 before 状态,以便我可以比较 new_haveCount 值是否真的在改变?或者更好的是,首先要防止双火?

@EnvironmentObject var modelData: ModelData

specificsspecificsFirebase 都是结构。

选择器代码

            Picker(selection: $modelData.figureArray[figureIndex].specifics.specificsFirebase.new_haveCount,label: Text("  \(modelData.figureArray[figureIndex].specifics.specificsFirebase.new_haveCount) ")) {
                ForEach(0 ..< 20) {
                    Text("\(kSpecificType_Labels[1]) \($0) \(kNewText.lowercased())")
                }
            }
            .onChange(of: modelData.figureArray[figureIndex].specifics.specificsFirebase.new_haveCount) { _ in
                saveSpecifics()
            }

apple dev page 来看,.onChange 似乎具有之前和之后的属性

struct PlayerView : View {
var episode: Episode
@State private var playState: PlayState = .paused

var body: some View {
    vstack {
        Text(episode.title)
        Text(episode.showTitle)
        PlayButton(playState: $playState)
    }
    .onChange(of: playState) { [playState] newState in
        model.playStateDidChange(from: playState,to: newState)
    }
}
}

如果有帮助,请查看完整版

import SwiftUI
import Firebase

struct SpecificsEntryView: View {
@EnvironmentObject var modelData: ModelData

let figure: figure

var figureIndex: Int {
    modelData.figureArray.firstIndex(where: { $0.id == figure.id })!
}

var body: some View {
    HStack(spacing: 4) {
        // new labels
        vstack(alignment: .leading,spacing: 4) {
            ForEach(kSpecificType_Labels,id: \.self) { label in
                Text(label)
                    .frame(maxHeight: .infinity)
                    .padding(.bottom,2)
                Divider()
            }
        }
        
        // new values
        vstack(alignment: .center,spacing: 4) {
            Text(kNewText)
                .frame(maxHeight: .infinity)
                .padding(.bottom,2)
            Divider()
            Picker(selection: $modelData.figureArray[figureIndex].specifics.specificsFirebase.new_haveCount,label: Text("  \(modelData.figureArray[figureIndex].specifics.specificsFirebase.new_haveCount) ")) {
                ForEach(0 ..< 20) {
                    Text("\(kSpecificType_Labels[1]) \($0) \(kNewText.lowercased())")
                }
            }
            .onChange(of: modelData.figureArray[figureIndex].specifics.specificsFirebase.new_haveCount) { _ in
                saveSpecifics()
            }
            .frame(maxHeight: .infinity)
            .padding(.bottom,2)
            .pickerStyle(MenuPickerStyle())
            Divider()
            Picker(selection: $modelData.figureArray[figureIndex].specifics.specificsFirebase.new_wantCount,label: Text("  \(modelData.figureArray[figureIndex].specifics.specificsFirebase.new_wantCount)  ")) {
                ForEach(0 ..< 20) {
                    Text("\(kSpecificType_Labels[2]) \($0) \(kNewText.lowercased())")
                }
            }
            .onChange(of: modelData.figureArray[figureIndex].specifics.specificsFirebase.new_wantCount) { _ in
                saveSpecifics()
            }
            .frame(maxHeight: .infinity)
            .padding(.bottom,2)
            .pickerStyle(MenuPickerStyle())
            Divider()
            Picker(selection: $modelData.figureArray[figureIndex].specifics.specificsFirebase.new_sellCount,label: Text("  \(modelData.figureArray[figureIndex].specifics.specificsFirebase.new_sellCount)  ")) {
                ForEach(0 ..< 20) {
                    Text("\(kSpecificType_Labels[3]) \($0) \(kNewText.lowercased())")
                }
            }
            .onChange(of: modelData.figureArray[figureIndex].specifics.specificsFirebase.new_sellCount) { _ in
                saveSpecifics()
            }
            .frame(maxHeight: .infinity)
            .padding(.bottom,2)
            .pickerStyle(MenuPickerStyle())
            Divider()
            Picker(selection: $modelData.figureArray[figureIndex].specifics.specificsFirebase.new_orderCount,label: Text("  \(modelData.figureArray[figureIndex].specifics.specificsFirebase.new_orderCount)  ")) {
                ForEach(0 ..< 20) {
                    Text("\(kSpecificType_Labels[4]) \($0) \(kNewText.lowercased())")
                }
            }
            .onChange(of: modelData.figureArray[figureIndex].specifics.specificsFirebase.new_orderCount) { _ in
                saveSpecifics()
            }
            .frame(maxHeight: .infinity)
            .padding(.bottom,2)
            .pickerStyle(MenuPickerStyle())
            Divider()
        } // end new vstack

        Divider() // vertical

        // loose values
        vstack(alignment: .center,spacing: 4) {
            Text(kLooseText)
                .frame(maxHeight: .infinity)
                .padding(.bottom,2)
            Divider()
            Picker(selection: $modelData.figureArray[figureIndex].specifics.specificsFirebase.loose_haveCount,label: Text("  \(modelData.figureArray[figureIndex].specifics.specificsFirebase.loose_haveCount)  ")) {
                ForEach(0 ..< 20) {
                    Text("\(kSpecificType_Labels[1]) \($0) \(kNewText.lowercased())")
                }
            }
            .onChange(of: modelData.figureArray[figureIndex].specifics.specificsFirebase.loose_haveCount) { _ in
                saveSpecifics()
            }
            .frame(maxHeight: .infinity)
            .padding(.bottom,2)
            .pickerStyle(MenuPickerStyle())
            Divider()
            Picker(selection: $modelData.figureArray[figureIndex].specifics.specificsFirebase.loose_wantCount,label: Text("  \(modelData.figureArray[figureIndex].specifics.specificsFirebase.loose_wantCount)  ")) {
                ForEach(0 ..< 20) {
                    Text("\(kSpecificType_Labels[2]) \($0) \(kNewText.lowercased())")
                }
            }
            .onChange(of: modelData.figureArray[figureIndex].specifics.specificsFirebase.loose_wantCount) { newVal in
                print("\(modelData.figureArray[figureIndex].specifics.specificsFirebase.loose_wantCount) to \(newVal)")
                saveSpecifics()
            }
            .frame(maxHeight: .infinity)
            .padding(.bottom,2)
            .pickerStyle(MenuPickerStyle())
            Divider()
            Picker(selection: $modelData.figureArray[figureIndex].specifics.specificsFirebase.loose_sellCount,label: Text("  \(modelData.figureArray[figureIndex].specifics.specificsFirebase.loose_sellCount)  ")) {
                ForEach(0 ..< 20) {
                    Text("\(kSpecificType_Labels[3]) \($0) \(kNewText.lowercased())")
                }
            }
            .onChange(of: modelData.figureArray[figureIndex].specifics.specificsFirebase.loose_sellCount) { _ in
                saveSpecifics()
            }
            .frame(maxHeight: .infinity)
            .padding(.bottom,2)
            .pickerStyle(MenuPickerStyle())
            Divider()
            TextField("Order from",text: $modelData.figureArray[figureIndex].specifics.specificsFirebase.new_orderText,onCommit: {
                        saveSpecifics()
                      })
                .frame(maxWidth: .infinity,maxHeight: .infinity,alignment: .leading)
                .padding(.bottom,2)
                .background(Color(.systemGray5))
                .cornerRadius(4)
            Divider()
        } // end loose vstack
    } // end all hstack specifics
    .fixedSize(horizontal: false,vertical: true)
    .font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/)
} // end body

// save specifics on update
func saveSpecifics() {

    // Inject Firebase authentication
    let userID = Auth.auth().currentUser?.uid
    modelData.figureArray[figureIndex].specifics.specificsFirebase.saveSpecifics(userID: userID!)
}
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)