BenJ
BenJ

Reputation: 197

UITableview appends new cells below old when I call reloadData()

Problem:

I want my tableView to clear the old cells when I reload data from the data source. When I load the table on an unwind segue, the data source gets all new data from a json blob, but the old cells in the table persist when I call reloadData() even though my data source array contains only new data.

Code:

Main View Controller:

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    var sourceArray=[String]()
    var otherClassVariable: Any?

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

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell")
        cell.textLabel?.text = sourceArray[indexPath.row]
        return cell
    }

    func getNewDataAndUpdateTable() {
        //Remove all from sourceArray
        self.sourceArray.removeAll()
        let param = self.otherClassVariable
        let url = URL(string: "https://myurl.com/"+param)!

        let task = URLSession.shared.dataTask(with: url) {(data, response, error) in

            if error != nil {
                print(error as! String)
            } else {
                if let urlContent = data {
                    do {
                        let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as! Array<Dictionary<String, Any>>

                        //Repopulate source Array
                        for thing in jsonResponse {
                            self.sourceArray.append(thing)
                        }

                        Dispatch.main.async {
                            //Reload data in main thread
                            self.tableView.reloadData()
                        }
                    } catch {
                        print("json failed")
                    }
                }
            }
        }

        task.resume()

    }

    override func viewDidLoad() {
        super.viewDidLoad()

        getNewDataAndUpdateTable()

    }

    @IBAction func unwindToViewController(_ sender: UIStoryboardSegue) {
        if sender.source is SecondViewController {
            if let senderVC = sender.source as? SecondViewController{
                self.otherClassVariable = senderVC.updatedOtherClassVariable as String!
                getNewDataAndUpdateTable()
            }
        }
    }
}

Upvotes: 1

Views: 69

Answers (1)

Ivan Smetanin
Ivan Smetanin

Reputation: 2039

It's so because you're appending new data to your sourceArray but you should assign it.

Updated code:

func getNewDataAndUpdateTable() {
    //Remove all from sourceArray
    self.sourceArray.removeAll()
    let param = self.otherClassVariable
    let url = URL(string: "https://myurl.com/"+param)!

    let task = URLSession.shared.dataTask(with: url) {(data, response, error) in

        if error != nil {
            print(error as! String)
        } else {
            if let urlContent = data {
                do {
                    let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as! Array<Dictionary<String, Any>>

                    //Repopulate source Array
                    self.sourceArray = jsonResponse // Assign response to the source array

                    Dispatch.main.async {
                        //Reload data in main thread
                        self.tableView.reloadData()
                    }
                } catch {
                    print("json failed")
                }
            }
        }
    }

    task.resume()

}

Upvotes: 2

Related Questions