Save & Retrieve TableViewCell checkmark using NSUserDefaults in Swift

前端 未结 2 1551
南方客
南方客 2020-12-20 09:25

I am trying to save and retrieve tableViewCell checkmark using NSUserDefaults.My partial code as below.From the code,I can able to select or deselect cell using UITableViewC

相关标签:
2条回答
  • 2020-12-20 09:49
    • First of all create a class Item as data source with a name and selected property.

      class Item {
        let name : String
        var selected = false
      
        init(name: String) {
          self.name = name
        }
      }
      
    • Declare the data source array

      var myItems = [Item]()
      
    • Create the items this way

      let item = Item(name:"Foo") // your former string value, `selected` is false by default.
      myItems.append(item)
      
    • In applicationDidFinishLaunching register an empty string array as default value for key selectedCells

      let defaults = NSUserDefaults.standardUserDefaults()
      let defaultValues = ["selectedCells" : [String]()]
      defaults.registerDefaults(defaultValues)
      
    • To read all selected cells from user defaults get the string array and set the property selected of all corresponding items to true. Then reload the table view. The forced unwrapping is safe because the key/value is pre-registered and always non-optional. Important: Make sure that readDefaults() is always called after registering the default values.

      func readDefaults()
      {
        let defaults = NSUserDefaults.standardUserDefaults()
        let selectedItems = defaults.stringArrayForKey("selectedCells")!
        for item in myItems {
          item.selected = selectedItems.contains(item.name)
        }
        tableView.reloadData()
      }
      
    • In cellForRowAtIndexPath set both properties accordingly

      func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      
        let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath)
        let item = myItems[indexPath.row]
        cell.textLabel!.text = item.name
        cell.accessoryType = item.selected ? .Checkmark : .None
        cell.selectionStyle = .None
        cell.tintColor = UIColor.greenColor()
      
        return cell
      }
      
    • To save the data filter all items whose selected property is true, map it to the names and save the array.

      func saveDefaults() {
        let selectedCells = myItems.filter { $0.selected }.map { $0.name }
        let defaults = NSUserDefaults.standardUserDefaults()
        defaults.setObject(selectedCells, forKey:"selectedCells")
      }
      
    • Now you should change the model in didSelectRowAtIndexPath and reload the row. This is much more efficient (and recommended) than manipulating the cell

      func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let item = myItems[indexPath.row]
        item.selected = true
        tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None)
      }
      
    0 讨论(0)
  • 2020-12-20 09:56

    My example, i Load in tableView set in DetailController

    Model ----

    struct TheoryData {
    
        var id: String
        var theoryText: String
        var theoryModes: String
        var theoryImage: String
        var like: Bool
    }
    

    Read values

       var theoryData = [TheoryData]()
    
    private func readDefaults() {
        let defaults = UserDefaults.standard
        let selectedItems = defaults.stringArray(forKey: "selectedCells") ?? []
        
        (0..<theoryData.count).forEach { i in
            theoryData[i].like = selectedItems.contains(theoryData[i].id)
        }
        menuTableView.reloadData()
    }
    
     override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        readDefaults()
    }
    

    In cell

    let theory = theoryData[indexPath.row]
    cell.likeImage.image = theory.like ? #imageLiteral(resourceName: "heart-icon") : #imageLiteral(resourceName: "heart-empty-icon")
    

    Save state in UserDefault

        @IBAction func likeButtonTapped(_ sender: UIButton) {
            theoryData.like.toggle()
            let likeIcon = theoryData.like ? #imageLiteral(resourceName: "heart-icon") : #imageLiteral(resourceName: "heart-empty-icon")
            likeButton.setImage(likeIcon, for: .normal)
            saveSelection()
        }
        
        private func saveSelection() {
            let defaults = UserDefaults.standard
            var selectedItems = defaults.stringArray(forKey: "selectedCell") ?? []
            
            if theoryData.like {
                selectedItems.append(theoryData.id)
            } else {
                selectedItems = selectedItems.filter{ $0 != theoryData.id }
            }
            print(selectedItems)
            defaults.setValue(selectedItems, forKey: "selectedCell")
        }
     }
    
    0 讨论(0)
提交回复
热议问题