UserDefaults 存储数组中的按钮选择
Posted
技术标签:
【中文标题】UserDefaults 存储数组中的按钮选择【英文标题】:UserDefaults to store a button selection from an array 【发布时间】:2021-01-01 21:05:27 【问题描述】:正在努力弄清楚如何在此处存储按钮的选择,并希望有人能提供帮助。我首先进行数据库查询以返回结果列表,每个项目都有一个按钮,单击该按钮时,它将始终显示他们单击了它。它当前的工作方式,当我在页面上时,我可以单击添加,它可以工作并写入数据库,当单击它时它会更改为“撤消”按钮,这也可以按照我想要的方式工作,但是一旦我离开此视图并返回,它就会通过“添加”按钮恢复为原始视图。如果用户按下“添加”,我希望它保持不变,并在用户返回此屏幕时始终显示“撤消”按钮。任何帮助都会很棒,因为我对此很陌生。
代码如下:
主视图
struct AdditemView: View
let movie: Movie
@State var movieitems = [MovieitemsModel]()
@State var movieID = ""
@State var selection = ""
var body: some View
VStack
ForEach(movieitems.indices, id: \.self) i in
HStack
Text(movieitems[i].name)
Spacer()
if movieitems[i].selected == false
Button(action:
self.selection = movieitems[i].name
self.movieitems[i].selected = true
self.yesitem()
)
Text("Add")
else
HStack
Text("Added!")
Button(action:
self.selection = movieitems[i].name
self.movieitems[i].selected = false
self.undoitem()
)
Text("Undo")
Divider()
.onAppear
self.movieID = "\(movie.id)"
fetchitems()
func fetchitems()
let db = Firestore.firestore()
db.collection("movies").document("\(self.movieID)").collection("items").getDocuments NewQuerySnapshot, error in
guard let documents = NewQuerySnapshot?.documents else
print("No Documents")
return
movieitems = documents.map (NewQueryDocumentSnapshot) -> MovieitemsModel in
let data = NewQueryDocumentSnapshot.data()
let name = data["name"] as? String ?? ""
let yes = data["yes"] as? Int?
let no = data["no"] as? Int?
return MovieitemsModel(name: name, yes: yes! ?? 0, no: no! ?? 0)
func yesitem()
let db = Firestore.firestore()
db.collection("movies").document(movieID).collection("items").document("\(self.selection)").updateData([AnyHashable("yes"): FieldValue.increment(Int64(1))])
func undoitem()
let db = Firestore.firestore()
db.collection("movies").document(movieID).collection("items").document("\(self.selection)").updateData([AnyHashable("yes"): FieldValue.increment(Int64(-1))])
物品模型
struct MovieitemsModel: Identifiable
var id: String = UUID().uuidString
var name: String
var yes: Int
var no: Int
var selected:Bool = false
【问题讨论】:
我不确定 UserSettings 是您想要使用的。那是一家非常有限的商店。既然您已经在使用 Firestore,为什么不将您的数据保存在那里? 没有用户账户,所有用户都可以按添加按钮(会有一个“添加”的总和)。如果没有帐户,我会在哪里为每个用户在数据库中存储这些信息? (我希望这个问题有意义) 如果没有用户帐户并且选择是递增的,您可以通过递增模型上的整数属性(而不是布尔值)将数据保存回 Firebase。但是,您仍然需要一些方法来跟踪当前用户的选择 - 用户默认值可以用于该位(这将避免用户每次打开应用程序时都能够重新增加计数)。例如,您可以将具有相应布尔选择的电影 ID 字典保存到用户默认值,然后在视图加载时检查此项,以便将相应的项目标记为已选择。 你需要调整你的模型;您需要以某种方式跟踪添加的状态,以便知道哪些电影已添加并保存,哪些电影已添加但尚未保存。 @Chris 它由所有用户共享,因此如果 1000 人单击“添加”按钮,每个用户都会在该电影的该项目上看到“1000” 【参考方案1】:这样做的一种方法是编写另一个函数,将电影数据保存回数据库并在每个按钮的操作处理程序中调用它。
// Example button
Button(action:
self.selection = movieitems[i].name
self.movieitems[i].selected = true
self.undoitem()
self.saveItems()
)
Text("Undo")
// The save method
func saveItems():
// Your Firebase saving code here
【讨论】:
我不清楚 saveItems 函数中会保存什么。 好的,我想我明白了。问题是我没有用户帐户,应用程序的所有用户都可以按下按钮(显示总和),但所有用户只能按下一次,我需要应用程序知道个人用户是否按下它。 哦,这个想法其实很有趣。我没有想到这一点。它增加了相当多的复杂性,必须为电影和用户默认值中的所有选择创建新记录。我想我希望它更简单,只需将项目模型中的selected
存储在 userdefaults 中,因此当它通过 ForEach 循环时,它会知道该特定电影项 [i] 的 selected
是真还是假跨度>
@SeanForReal 您可以使用一行代码(如this example)在一次“开始”中将数组或字典存储在用户默认值中。它不需要是整个数据模型;只是每部电影的唯一 ID,带有一个布尔值来表示用户是否选择了它。
非常感谢!我现在正在处理它并遇到了一些问题,但我认为这是一个很好的解决方案。以上是关于UserDefaults 存储数组中的按钮选择的主要内容,如果未能解决你的问题,请参考以下文章
您是不是能够跨不同的视图控制器/.swift 文件检索存储在 UserDefaults 中的数据?
将 IAP 存储在 UserDefaults 中,这样用户就不需要在每次按下“可购买”按钮时恢复购买