Есть множество способов сделать это.Я обычно предпочитаю назначить модель для TableViewCell и позволить ячейке отображать саму себя.
Учитывая, что у вас есть структура модели, подобная этой:
struct MyData: Codable {
let planets: [Planet]
}
struct Planet: Codable {
let name: String
let continents: [Continent]
}
struct Continent: Codable {
let name: String
let countries: [Country]
}
struct Country: Codable {
let name: String
let states: [State]
}
struct State: Codable {
let name: String
let cities: [City]
}
struct City: Codable {
let name: String
}
и PlanetCell, подобная этой:
class PlanetCell: UITableViewCell {
static let identifier = "planetCell"
@IBOutlet weak var titleLabel: UILabel!
var planet: Planet! {
didSet {
renderSelf()
}
}
private func renderSelf() {
titleLabel.text = planet.name
}
}
В вашем DataSource для первого TableView вы бы отобразили планету:
// MARK: - UITableViewDataSource
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: PlanetCell.identifier, for: indexPath) as! PlanetCell
cell.planet = planets[indexPath.row]
return cell
}
теперь, когда вы выбираете PlanetCell, просто используйте методы делегата из UITableViewDelegate для выполнения перехода и передачи данных в вашследующий ViewController.
// MARK: - UITableViewDelegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "showPlanet", sender: planets[indexPath.row])
}
// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let continentsViewController = segue.destination as? ContinentsViewController else {
return
}
continentsViewController.continents = (sender as! Planet).continents
}
просто примените ту же логику ко всем вашим контроллерам представления.