skip to Main Content

I have the below code where each item in the UITableView goes to the same view controller screen and I am trying to create a segue to the second view controller:

import UIKit

class ItemsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, ItemsBaseCoordinated {
    
    var coordinator: ItemsBaseCoordinator?
    private let myArray: NSArray = ["India","Canada","Australia"]
    private var myTableView: UITableView!
    
    init(coordinator: ItemsBaseCoordinator) {
        super.init(nibName: nil, bundle: nil)
        self.coordinator = coordinator
        title = "Items"
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()

        //let barHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height
        let barHeight = UIApplication.shared.connectedScenes
                .filter {$0.activationState == .foregroundActive }
                .map {$0 as? UIWindowScene }
                .compactMap { $0 }
                .first?.windows
                .filter({ $0.isKeyWindow }).first?
                .windowScene?.statusBarManager?.statusBarFrame.height ?? 0
        let displayWidth: CGFloat = self.view.frame.width
        let displayHeight: CGFloat = self.view.frame.height

        myTableView = UITableView(frame: CGRect(x: 0, y: barHeight, width: displayWidth, height: displayHeight - barHeight))
        myTableView.register(UITableViewCell.self, forCellReuseIdentifier: "MyCell")
        myTableView.dataSource = self
        myTableView.delegate = self
        self.view.addSubview(myTableView)
    }
    
    

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for: indexPath as IndexPath)
        cell.textLabel!.text = "(myArray[indexPath.row])"
        return cell
    }
    
    
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        print("Selected Row (indexPath.row)")
        let nextVC = SecondViewController()
        

        // Push to next view
        navigationController?.pushViewController(nextVC, animated: true)
    }
    
    
    
}

class SecondViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .systemRed
        title = "bruh"
    }
}

The below video represents what I actually want:

enter image description here

Currently each item goes to the same viewcontroller screen, how do I perform this segue with identifiers because I am not even using storyboards

2

Answers


  1. If you aren’t using Interface Builder (wise choice) then you aren’t segueing (segue is an IB term), you are simply pushing. In your code, when you instantiate the second view controller, you don’t do anything special to it before you push to it, so how could you even see a difference between different cells?

    Create a property in the second view controller, inject it with a value based on the index path of the selected cell, and then confirm that it’s all hooked up. If it is, then inject it with a meaningful value that you can use, not the index path in my example.

    class SecondViewController: UIViewController {
        var cellPath: IndexPath?
        
        override func viewDidLoad() {
            super.viewDidLoad()
            view.backgroundColor = .systemRed
            title = "bruh"
            print(cellPath ?? "still not right")
        }
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let nextVC = SecondViewController()
        nextVC.cellPath = indexPath
        navigationController?.pushViewController(nextVC, animated: true)
    }
    
    Login or Signup to reply.
  2. You seem to be a long way off where you want to get to. Your second VC will need the able to render the content and at the moment it can do none of that. However to address the question of passing the data between VCs, the easier way would be to inject the data you need. There are many different approaches, but a simple one would be to…

    Create a struct to hold the data you want, and then hold an array of these rather than an array of Strings as your primary data source. For example:

    struct CountryInfo {
      let name: String
      let capital: String
      let flag: UIImage
      // etc...
    }
    
    

    and replace your myArray with an array of these structs populated with the appropriate data.

    Then in your initial VC’s cellForRowAt you can refer to the name property:

    cell.textLabel!.text = "(myArray[indexPath.row].name)"
    

    In your second VC you will need a property that allows the appropriate struct to be injected and then referenced for display

    class SecondViewController: UIViewController {
        var country: CountryInfo!
    
       //etc
    }
    

    Then you can inject the selected country’s info into the second VC in didSelectRowAt

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
       let nextVC = SecondViewController()
       nextVC.country = myArray[indexPath.row]
       navigationController?.pushViewController(nextVC, animated: true)
    }
    

    Then all you have to do is display this data, which can be done from the second VC’s viewDidLoad()

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search