Reputation: 1163
I am completely new to swift developing. I want to implement a UI table view which it could shows a list of my items in array like the image below
It works fine but when I move items places and then I touch done button, after restart the app, every changes that I have made, resets to its default. I searched a lot and I found that I should save it on user defaults. I read lots of articles but still I do not know what should I do with codes, I appreciate if some one could edit my codes the way I need (reordering changes could save on device and not refreshing each time I open the app)
here is my codes in viewController
// ViewController.swift
// Created by Sebastian Hette on 28.02.2017.
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var array = ["one", "two", "three", "four", "five"]
let defaults = UserDefaults.standard
//I defined user defaults here
struct Constants {
static let myKey = "myKey"
}
//I defined my static key here
@IBOutlet weak var myTableView: UITableView!
@IBOutlet weak var editButton: UIBarButtonItem!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return array.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
defaults.stringArray(forKey: Constants.myKey)
//I retrieve user defaults here
cell?.textLabel?.text = array[indexPath.row]
return cell!
}
//Allows reordering of cells
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool
{
return true
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
{
let item = array[sourceIndexPath.row]
array.remove(at: sourceIndexPath.row)
array.insert(item, at: destinationIndexPath.row)
}
@IBAction func edit(_ sender: Any)
{
myTableView.isEditing = !myTableView.isEditing
switch myTableView.isEditing {
case true:
editButton.title = "done"
case false:
editButton.title = "edit"
}
defaults.set(array, forKey: Constants.myKey)
//I saved my user defaults here
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Upvotes: 1
Views: 670
Reputation: 626
First you'll need a UserDefaults object:
let defaults = UserDefaults.standard
To save:
defaults.set(0, forKey: "myNumber")
defaults.set("hello", forKey: "myString")
defaults.set(["apple", "banana", "grape"], forKey: "myArray")
To retrieve:
defaults.integer(forKey: "myNumber")
defaults.string(forKey: "myString")
defaults.stringArray(forKey: "myArray") // you can also save any type of array by using defaults.array
You can save multiple types, including numbers (int, double, float, etc), strings, boolean, object, and arrays. I recommend storing the keys in a separate Constants or similar file, because typos in the key values could cause this not to work and you'll be banging your head on the wall trying to figure out a more complex reason as to why your app isn't working. An example:
static let myKey = "myKey"
and to use would be
Constants.myKey
By using UserDefaults your app will save the order of your data even after it closes. Instead of declaring an array in your ViewController, initialize your array in viewDidLoad.
EDIT:
You're almost there. I'm not seeing a viewDidLoad
method, which I believe you'll need. Here's a little sample I whipped up:
class ViewController: UIViewController {
var array = [String]() // declaring a String array
let defaults = UserDefaults.standard // where the data will be stored
override func viewDidLoad() {
super.viewDidLoad()
// this sets the array equal to the last saved array, or the default one if one has not been saved
array = defaults.stringArray(forKey: myKey) ?? ["one", "two", "three", "four", "five"]
}
}
Every time you are ready to save your new ordered array call defaults.set(array, forKey: myKey)
. In your cellForRowAtIndexPath
method, take out the line where you retrieve user defaults, you won't need it now that you're retrieving it on viewDidLoad
and setting it equal to your array variable.
And if it were me, I would save the user defaults as the last line in the moveRowAt
method.
Upvotes: 2