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 中,这样用户就不需要在每次按下“可购买”按钮时恢复购买

使用 UserDefaults 相互替换的值

在 UserDefaults 中存储自定义对象数组

存储/保存 @State 数组 (UserDefaults)

Swift 3.0:在 TableView 的 UserDefaults 中存储数组