Van
Van

Reputation: 127

Save state of favorite button in Table view Cell in NSUserDefaults

I've gone through many solutions for this kind of questions but I'm still stuck and don't know how to save the state of my button into NSUserDefaults.

Here is the picture for demo

This is my Tableview controller

override func viewDidLoad() {

    super.viewDidLoad()
    navigationItem.title = "Contacts"
    tableView.register(RecordCell.self, forCellReuseIdentifier: "cellId")
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let myCell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath as IndexPath) as! RecordCell


    myCell.starButton.tag = indexPath.row
    myCell.myTableViewController = self
    return myCell
}

This is my custom Cell class

class RecordCell: UITableViewCell {

var myTableViewController: HomepageController?

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    setupViews()
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

let nameLabel: UILabel = {
    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    label.font = UIFont (name: "SFCompactDisplay-Regular", size: 14)
    return label
}()
let companyLabel: UILabel = {
    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    label.font = UIFont (name: "SFCompactDisplay-Light", size: 10)
    return label
}()
let shortname: UILabel = {
    let label = UILabel()
    label.textColor = UIColor.white
    label.translatesAutoresizingMaskIntoConstraints = false
    label.font = UIFont (name: "SFCompactDisplay-Regular", size: 12)
    label.textAlignment = .center
    label.backgroundColor = UIColor(patternImage: UIImage(named: "avatar")!)
    return label
}()
let starButton: UIButton = {
    let button = UIButton(type: .system)
    button.setImage(UIImage(named: "star"), for: .normal)
    button.translatesAutoresizingMaskIntoConstraints = false
    return button
}()
let playButton: UIButton = {
    let button = UIButton(type: .system)
    button.setImage(UIImage(named: "playback"), for: .normal)
    button.translatesAutoresizingMaskIntoConstraints = false
    return button
}()

func setupViews() {
    addSubview(nameLabel)
    addSubview(companyLabel)
    addSubview(shortname)
    addSubview(starButton)
    addSubview(playButton)

    starButton.addTarget(self, action: #selector(RecordCell.starAction), for: .touchUpInside)

// playButton.addTarget(self, action: #selector(RecordCell.playAudio), for: .touchUpInside)

    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-8-[v4(40)]-8-[v0]-8-[v1(30)]-8-[v2(30)]-8-|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": nameLabel, "v1": starButton,"v2":playButton, "v4":shortname]))
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-56-[v3]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v3": companyLabel]))


    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-2-[v0][v3]-7-|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": nameLabel,"v3": companyLabel]))
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": starButton]))
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": playButton]))
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-2-[v0(40)]-7-|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": shortname]))

}

func starAction() {
    starButton.setImage(UIImage(named:"star-active"), for: .normal)
}

Upvotes: 0

Views: 1719

Answers (2)

Akhilrajtr
Akhilrajtr

Reputation: 5182

add tag as a variable in RecordCell class like

class RecordCell: UITableViewCell {

var myTableViewController: HomepageController?
var favID:Int = 0
.....//other code
}

in Viewcontroller

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let myCell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath as IndexPath) as! RecordCell

    myCell.favID = indexPath.row //set value to favID variable
    myCell.myTableViewController = self
    myCell.updateSelection() //call this method to update the selection
    return myCell
}

in RecordCell class

override func awakeFromNib() {
    super.awakeFromNib()
    updateSelection()
}

func updateSelection() {
    let key = "\(favID)" 
    let userDefault = UserDefault.standard
    let isFav = userDefault.bool(forKey: key)
    starButton.isSelected = isFav
}

let starButton: UIButton = {
    let button = UIButton(type: .system)
    button.setImage(UIImage(named: "star"), for: .normal) //add image for different states
    button.setImage(UIImage(named:"star-active"), for: .selected) //add image for different states
    button.translatesAutoresizingMaskIntoConstraints = false
    return button
}()

func setupViews() {
    ....
    ....//other code
    updateSelection()
}

func starAction() {
    starButton.isSelected = !starButton.isSelected //toggle selection
    let key = "\(favID)" 
    let userDefault = UserDefault.standard
    userDefault.set(starButton.isSelected, forKey: key)
    userDefault.synchronize()
}

this is an index based example, if possible you can use any unique identifier of the object that is displaying in the table as key. Or set a isFav variable in the data model itself.

Upvotes: 1

Brijesh Shiroya
Brijesh Shiroya

Reputation: 3383

func starAction() {

     let userDefault = UserDefault.standard
      userDefault.set(true, forKey: "KEY_IS_SELECTED")
    starButton.setImage(UIImage(named:"star-active"), for: .normal)
}

get favorite button state:

let userDefault = UserDefault.standard
let state = userDefault.bool(forKey: "KEY_IS_SELECTED")

//get stored state of button
//use state of button

Upvotes: 0

Related Questions