0

I am implementing a function that sends the title of the cell to the JSON file name of the next controller when clicking on a data table cell.

The data passes well, but the data arrives one by one late. If you click the first cell, the data is not gone, and if you click the second cell, the contents of the first cell are transferred.

Where do I adjust data going late one by one? Any ideas?

vc1

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        guard let nextViewController: SecondViewController = segue.destination as? SecondViewController else {
            return
        }
        guard let cell: UITableViewCell = sender as? UITableViewCell else {
            return
        }
        nextViewController.title = cell.textLabel?.text
        nextViewController.secondAssetName = jsonName
    }


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let country: Countries = countries[indexPath.row]
        jsonName = country.asset_name
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return countries.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MainCell", for: indexPath)
        let country: Countries = countries[indexPath.row]
        cell.imageView?.image = UIImage(named: "flag_" + country.asset_name)
        cell.textLabel?.text = country.korean_name
        return cell
    }
    
    // Data Transfer
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        guard let nextViewController: SecondViewController = segue.destination as? SecondViewController else {
            return
        }
        guard let cell: UITableViewCell = sender as? UITableViewCell else {
            return
        }
        nextViewController.title = cell.textLabel?.text
        nextViewController.secondAssetName = jsonName
    }
}

vc2

class SecondViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    var weathers = [Weather]()
    var secondAssetName: String?
    
    @IBOutlet weak var tableView: UITableView!
    
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        let jsonDecoder = JSONDecoder()
        guard let dataAsset = NSDataAsset(name: secondAssetName ?? "") else {
            return
        }
        do {
            weathers = try jsonDecoder.decode([Weather].self, from: dataAsset.data)
        } catch {
            print(error.localizedDescription)
        }
        tableView.reloadData()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.tableView.delegate = self
        self.tableView.dataSource = self
    }
    

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return weathers.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: CustomTableViewCell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomTableViewCell
        let weather: Weather = weathers[indexPath.row]
        
        switch weather.state {
        case 10:
            cell.cellImageView?.image = UIImage(named: "sunny.png")
        case 11:
            cell.cellImageView?.image = UIImage(named: "cloudy.png")
        case 12:
            cell.cellImageView?.image = UIImage(named: "rainy.png")
        case 13:
            cell.cellImageView?.image = UIImage(named: "snowy.png")
        default:
            return cell
        }
        cell.cityNameLabel.text = weather.city_name
        cell.temperatureLabel.text = String(weather.celsius)
        cell.rainfallProbabilityLabel.text = String(weather.rainfall_probability)
        return cell
    }
}
jrturton
  • 118,105
  • 32
  • 252
  • 268
Hyunwoo
  • 21
  • 1
  • 6

1 Answers1

1

Add breakpoints to your code. You should see where the problem is. prepare(for: sender:) is being called before tableView(_: didSelectRowAt:), so the first time you tap a cell, jsonName is nil during prepare, then it gets set during didSelect. The second time you tap it, jsonName has the value from the first tap, then it gets updated after.

Put all of your logic in one place. Remove the didSelect method, and update prepare like so:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        
        guard let nextViewController: SecondViewController = segue.destination as? SecondViewController else {
            return
        }
        guard let cell: UITableViewCell = sender as? UITableViewCell else {
            return
        }
        guard let indexPath = tableView.indexPath(for: cell) else {
            return
        }

        let country: Countries = countries[indexPath.row]
        nextViewController.title = country.korean_name
        nextViewController.secondAssetName = country.asset_name
    }
jrturton
  • 118,105
  • 32
  • 252
  • 268