如何解决SwiftUI2, Picker .onChange 触发两次需要更改之前和之后的值
我遇到了类似于以下帖子 .onReceive firing twice 的问题。
我有一个触发 .onChange
两次的选择器。我正在为选择器使用模型数据环境对象。
有没有办法让我获得 before 状态,以便我可以比较 new_haveCount
值是否真的在改变?或者更好的是,首先要防止双火?
@EnvironmentObject var modelData: ModelData
specifics
和 specificsFirebase
都是结构。
选择器代码
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 举报,一经查实,本站将立刻删除。