AltBrian
AltBrian

Reputation: 2572

pushing data to UITableView is not showing

I am trying to push data from UIViewController to a UITableView. Now I am able to push one piece of data to the cell and it appears fine. The problem I am having if I go back and to push more data it just overrides the cell. Rather than going on to another cell. I have tried the suggestion from the this post and self.tableView.reloadData(). This does not seem to have solved the issue I have. Below is the code that I have written.

class PredictorTableViewController: UITableViewController {
    var predictorTrack = ""
    var firstDriver = ""
    var secondDriver = ""
    var thirdDriver = ""

    var grandPrix = [GrandPrix]()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.grandPrix.append(GrandPrix(granPrix: predictorTrack, firstDriver: firstDriver, secondDriver: secondDriver, thirdDriver: thirdDriver))
        self.tableView.reloadData()
        self.navigationItem.title = "Predictor"
        let backbutton = UIButton(type: .custom)
        backbutton.setTitle(" Back", for: .normal)
        backbutton.setTitleColor(.blue, for: .normal)
        backbutton.addTarget(self, action: #selector(self.backbuttonpressed), for: .touchUpInside)

        self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backbutton)
        setupNavBar()

    }

    @objc func backbuttonpressed() {
        dismiss(animated: true, completion: nil)
    }

    func setupNavBar(){
        navigationController?.navigationBar.prefersLargeTitles = true
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return grandPrix.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! GrandPrixTableViewCell
        let race = self.grandPrix[indexPath.row]
        // Configure the cell...
        cell.grandPrix.text = race.grandPrix
        cell.firstPostion.text = race.firstDriver
        cell.secondPosition.text = race.secondDriver
        cell.thirdPostion.text = race.thirdDriver

        return cell
    }

Below is the function to prepare for segue.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "getPredictor" {
        let predictorVC = segue.destination as! UINavigationController
        let vc = predictorVC.topViewController as! PredictorTableViewController
        vc.predictorTrack = TrackTextField.text!
        vc.firstDriver = firstTextField.text!
        vc.secondDriver = secondTextField.text!
        vc.thirdDriver = thirdTextField.text!
    }
}

Upvotes: 0

Views: 113

Answers (1)

Tomas Jablonskis
Tomas Jablonskis

Reputation: 4376

Your problem is that whenever your go back to previous UIViewConntroller instance of PredictorTableViewController gets deleted from the memory, so all of the data that is associated with it is also gone (grandPrix array).

I can suggest you 3 solutions:


FIRST

Keep your grandPrix array in parent UIViewController and pass it in to PredictorTableViewController when segue is performed like so:

var grandPrix = [GrandPrix]()

...

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "getPredictor" {
        let predictorVC = segue.destination as! UINavigationController
        let vc = predictorVC.topViewController as! PredictorTableViewController

        // append new GrandPrix to local array
        self.grandPrix.append(GrandPrix(granPrix: TrackTextField.text!, firstDriver: firstTextField.text!, secondDriver: secondTextField.text!, thirdDriver: thirdTextField.text!)) 

        // important part: pass local data to destination
        vc.grandPrix = self.grandPrix    
    }
}

SECOND

Keep PredictorTableViewController as a strong reference in parent UIViewCointroller and manually push PredictorTableViewController to UINavigationController when you need it.

// Strong lazy reference
lazy var predicatorController: PredicatorTableViewController = {

    // If needed, this can be loaded from a NIB or Storyboard
    return PredicatorTableViewController()
}()

To use this call following UINavigationController function:

// generate new data for predicatorController and append it to grandPrix array
predicatorController.grandPrix.append(...)

// show predicatorController
self.navigationController?.pushViewController(predicatorController, animated: true)

P.S. with this solutions DO NOT use segues.


THIRD

Same idea as first suggestion, but data of grandPrix array will be stored in local cache (CoreData database for example). You will have to write local cache data retrieval/storing functions and use it accordingly when you need to access existing and store new GrandPrix objects into your local cache.


Good luck :)

Upvotes: 1

Related Questions