【发布时间】:2021-06-05 23:48:55
【问题描述】:
我遇到了类似于以下帖子 .onReceive firing twice 的问题。
我有一个可以触发.onChange 两次的选择器。我正在为选择器使用模型数据环境对象。
有没有办法让我获得之前的状态,以便我可以比较 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似乎有一个before andofter属性。
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!)
}
}
【问题讨论】:
-
您问题的后半部分似乎在回答前半部分——您在从 Apple 开发者页面实现这个想法时遇到问题吗?
-
共享代码不足以重现问题。
-
正确,我不知道 [playState] 点
.onChange(of: playState) { [playState] newState in中的内容。当我输入modelData.figureArray[figureIndex].specifics.specificsFirebase.new_haveCount时,我收到一个错误“预期为‘弱’、‘无主’或捕获列表中没有说明符” -
如果我执行以下
newVal in print("\(modelData.figureArray[figureIndex].specifics.specificsFirebase.loose_wantCount) to \(newVal)")我得到3 to 3或任何新值,打印两次。
标签: ios swiftui onchange picker