danutha danutha - 1 month ago 15
iOS Question

Data in the UITableView get duplicated when back button is pressed

I working on a project that is written in swift 3.0. My requirement is to save data (on CoreData) that I enter on some text fields and populate one of those attributes in to a table view, thus once a row is selected I wants to update that record (re-assign values on my text fields and save).

Basically I have an entity named "Task" and it got three attributes, and I wants to populate one of those attributes(called "name") that I have saved on core data, in to a table view. Hence when I wants to edit the data that I entered, I tap on a row and it'll direct me to the ViewController where I initially entered those data. However when I click the back button without saving the data it'll duplicate the array and populate in my table view. how can I stop this. The code of the table view class as follow.

import UIKit
import CoreData

class TableViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

@IBOutlet weak var tableView: UITableView!

var stores = [Store] ()

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

override func viewDidLoad() {
super.viewDidLoad()

self.tableView.reloadData()

// Do any additional setup after loading the view.
}

override func viewDidAppear(_ animated: Bool) {

let request = NSFetchRequest <NSFetchRequestResult> (entityName: "Store")
request.returnsObjectsAsFaults = false



do {

let results = try context.fetch(request) as! [Store]



// check data existance
if results.count>0 {
print(results.count)

for resultGot in results {

if let expName = resultGot.name {
print("expence name is :", expName)

stores += [resultGot]

print("my array is : \(stores)")
}
}
self.tableView.reloadData()
}

}catch{


print("No Data to load")
}


}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return stores.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = UITableViewCell ()


let store = stores [indexPath.row]
cell.textLabel?.text = store.name

//cell.textLabel?.text = myExpensesArray[indexPath.row]
return cell
}



@IBAction func nextButtonPressed(_ sender: AnyObject) {

}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "editStore", sender: nil)

}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "editStore"{

let v = segue.destination as! ViewController
let indexPath = self.tableView.indexPathForSelectedRow
let row = indexPath?.row
v.store = stores[row!]


}
}

Answer

This is happening because already loaded elements are present inside your array. When you came back to previously loaded ViewController its method viewWillAppear, viewDidAppear called everytime according to the viewController's life cycle.

You need to clear your previously loaded array using removeAll() method when you came back.

Use below code:

override func viewDidAppear(_ animated: Bool) {

    stores.removeAll()  // clears all element   

    let request = NSFetchRequest <NSFetchRequestResult> (entityName: "Store")
    request.returnsObjectsAsFaults = false

    do {
        let results = try context.fetch(request) as! [Store]
        // check data existance
        if results.count>0 {
            print(results.count)

            for resultGot in results {
                if let expName = resultGot.name {
                    print("expence name is :", expName)
                    stores += [resultGot]
                    print("my array is : \(stores)")
                }
            }
            self.tableView.reloadData()
        }

    }catch{
        print("No Data to load")
    }
}