Reputation: 10738
What is the proper way to delete rows from UITableView
and update array from NSUserDefaults?
In the following example I'm reading an array from NSUserDefaults
and feeding a UITableView
with its content, I'm also allowing the user to delete items in the UITableView
what I'm not sure is when to read and write to NSUserDefaults
so the table updates as soon as a row is deleted. As you can see I start by reading the array the in the viewDidLoad
method and re-saving it in the commitEditingStyle
method. With this method my table is not reloading when a row is deleted.
override func viewDidLoad() {
super.viewDidLoad()
// Lets assume that an array already exists in NSUserdefaults.
// Reading and filling array with content from NSUserDefaults.
let userDefaults = NSUserDefaults.standardUserDefaults()
var array:Array = userDefaults.objectForKey("myArrayKey") as? [String] ?? [String]()
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel!.text = array[indexPath.row]
return cell
}
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
array.removeAtIndex(indexPath.row)
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
// Save array to update NSUserDefaults
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setObject(array, forKey: "myArrayKey")
// Should I read from NSUserDefaults here right after saving and then reloadData()?
}
How is this usually handled?
Thanks
Upvotes: 2
Views: 1208
Reputation: 285079
Basically it's correct, but you should only save in user defaults if something has been deleted.
if editingStyle == .delete {
array.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
let userDefaults = UserDefaults.standard
userDefaults.set(array, forKey: "myArrayKey")
}
Reading the array back is not needed and not recommended.
In cellForRowAtIndexPath
reuse the cell, you need to specify the identifier in Interface Builder.
let cell = tableView.dequeueReusableCell(withIdentifier:"Cell", for: indexPath)
The data source array must be declared on the top level of the class
var array = [String]()
then assign the value in viewDidLoad
and reload the table view.
override func viewDidLoad() {
super.viewDidLoad()
let userDefaults = UserDefaults.standard
guard let data = userDefaults.array(forKey: "myArrayKey") as? [String] else {
return
}
array = data
tableView.reloadData()
}
Upvotes: 3