1

I have an app which uses collection view to fetch array of data.

I have added a button to the collection view cell via storyboard.. When the user clicks on the button its selected state changes. Which is working fine.

Then I tried to save and retrieve the bool value of the UIButton for key "isSelected" using NSUserDefaults.

This is how i change the bool value and save using NSUserDefault.

@IBAction func likeBtn(_ sender: UIButton) {

if sender.isSelected == false {


            sender.isSelected = true

            let defaults = UserDefaults.standard

            defaults.set(true, forKey: "isSelected")


        }

        else {


            sender.isSelected = false

            let defaults = UserDefaults.standard

            defaults.set(false, forKey: "isSelected")


        }
}

And at my cellForItemAt indexPath i tried fetching the bool value for the UIButton..

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = newsfeedColView.dequeueReusableCell(withReuseIdentifier: "NewsFeed", for: indexPath) as! NewsFeedCollectionViewCell

        cell.likeBtn.addTarget(self, action: #selector(NewsFeedViewController.likeBtn(_:)), for: UIControlEvents.touchUpInside)


        var defaults = UserDefaults.standard

        var state = defaults.bool(forKey: "isSelected")

        cell.likeBtn.isSelected = state

return cell

}

Everything works fine till i am using the app, but when i quit the app and open again, the saved bool value is assigned to the UIButton in each cell rather than just on the cell which I selected earlier using the app.

I think i have to specify the index path while saving using NSUserDefault. But can't figure out how as i am new to swift and Xcode.. Any help as how to go ahead .

Screen Shot of the viewcontroller

Any help...Been suck here for a longtime.. Cant figure out the way to tackle this situation... Please ..

Anish Rana
  • 45
  • 6
  • 1) You don't need to do userdefaults to acheive such. you can still refer to the button within `cellForItemAt` using `likeBtn.isSelected` 2) You should store the `index.row` in userdefaults 3) The button is related to the view of the viewController, it's not related to *every* cell. – mfaani Dec 01 '16 at 21:56
  • I am sorry but i didnt get what you trying to imply?? – Anish Rana Dec 01 '16 at 21:59
  • which part? 1,2,3? – mfaani Dec 01 '16 at 22:01
  • No the button is related to each cell. It is not in the view but in each collection view cell. – Anish Rana Dec 01 '16 at 22:03
  • Update your question with a screenshot of your viewController + button + collectionview inside storyboard. And I can explain better – mfaani Dec 01 '16 at 22:10
  • question updated .Please have a look.. – Anish Rana Dec 01 '16 at 22:12
  • small heart on the top right of the cell is the button which when pressed changes its selected state.. but when i relaunch the app the button selected state in every cell updates instead of the button i clicked in a particular index.row – Anish Rana Dec 01 '16 at 22:13
  • I'm not sure Anish, but I believe all my comments *may* have been wrong. See [here](http://stackoverflow.com/questions/16453205/use-a-button-on-a-uicollectionviewcell-to-display-data-from-an-array) and [here](http://stackoverflow.com/questions/13757762/getting-button-action-uicollectionview-cell). – mfaani Dec 01 '16 at 22:43

1 Answers1

0

As you are just using one value for all your tableView's rows, when you 'selected' is true, it will be true for all which is what is happening now. You really need database to save those 'selected' states for each rows. But you can use the UserDefaults as your quick DB if this is just a prototype. To do this, you need to use a different key for each 'isSelected' rows and use the button tag as key.

@IBAction func likeBtn(_ sender: UIButton) 
{
  if sender.isSelected == false {
    sender.isSelected = true

    let defaults = UserDefaults.standard
    defaults.set(true, forKey: "isSelected\(sender.tag)")
  }
  else {
    sender.isSelected = false
    let defaults = UserDefaults.standard
    defaults.set(false, forKey: "isSelected\(sender.tag)")
  }
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  let cell = newsfeedColView.dequeueReusableCell(withReuseIdentifier: "NewsFeed", for: indexPath) as! NewsFeedCollectionViewCell

  cell.likeBtn.addTarget(self, action: #selector(NewsFeedViewController.likeBtn(_:)), for: UIControlEvents.touchUpInside)

  let tag = indexPath.row
  cell.likeBtn.tag = tag
  var defaults = UserDefaults.standard
  var state = defaults.bool(forKey: "isSelected\(tag)")

  cell.likeBtn.isSelected = state

  return cell
}
Christian Abella
  • 5,747
  • 2
  • 30
  • 42
  • I tried this solution, but when the cell disappears or I relaunch the app the selected state of the button is reseted to the default state i.e. false. Cant figure out what i am doing wrong. Is this the right approach to handle such an issue or I should be using an alternative approach. – Anish Rana Dec 02 '16 at 05:20