Search code examples
swiftuinavigationcontrollerios6seguedidselectrowatindexpath

Swift 3 Segue Q!- Prototype Cell to Multiple VCs - Using didSelectRowAtIndexPath


I am relatively new to Swift - developing an app for my hospital (I'm a resident physician) that's essentially a mobile reference tool that I'm building with a series of tableViews.

PROBLEM: I cant get my Segues to work from my Prototype cells to multiple VCs.

  • My initial VC is a tableVC, with prototype cells that I built into two sections using a nested array. Seen here
  • The destination VCs are also TableVCs, I want each tableCell of the initialVC to segue to a different destination TableVC.
  • I was able to set some Segues from my initialTVC to the destinationTVCs, I also have embedded a Navigation Controller --> Here's what my storyboard setup looks like

What I'm trying to do for the Segues:

  1. Set up the segue ID that I gave each segue in storyboard using the prepareForSegue function

  2. Use didSelectRowAtIndexPath, with some If statements specifying which cell I want to do which segue, to execute the segue.

  3. Keep that Storyboard Navigation controller in place - love the functionality and easy implementation it provides considering I'm going to add one more level of these segues as "submenus" before getting to my detailView pages.

Here's my Swift 3 code:

//  MainTableViewController.swift

import UIKit

class MainTableViewController: UITableViewController {

    var MainTitleArray = [["Children and Pregnant Women", "Mental Health and Addiction", "Hunger and Food Insecurity", "Legal Aid", "Housing, Heat, and Emergency Assistance", "New Immigrants, Refugees, and the Underserved", "The Uninsured and the Underinsured"], ["Primers and the Private Sector", "Federal Programs", "Social Securty"]]
    var SubTitleArray = [["Resources for the most vulnerable in the family", "The programs to help those who need it", "When every night is a worry about food on the table", "How to defend yourself in a complicated system", "HEalth follows you into the home", "Your patient needs help - can they sign up worry-free?", "What to do when your options are limited"], ["What you need to know","Medicare Medicaid - What are they?","Disability and Insurance"]]



    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 90           
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {

       return MainTitleArray.count
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return MainTitleArray[section].count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
     let cell = tableView.dequeueReusableCell(withIdentifier: "MainCell", for: indexPath) as! MainTableViewCell

     cell.MainTitleLabel.text = MainTitleArray[indexPath.section][indexPath.row]

     cell.MainSubTitleLabel.text = SubTitleArray[indexPath.section][indexPath.row]

     return cell}


  override  func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        if (indexPath.section == 0) && (indexPath.row == 0) {
            self.performSegue(withIdentifier: "CPWSegue", sender: indexPath);
        }
        else { self.performSegue(withIdentifier: "MHASegue", sender: indexPath)

        }}

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "CPWSegue" {
            let destVC = segue.destination as! CPWTableViewController
            destVC.VCName = "CPW"}

        }
}

I build this successfully but the segues just arent working still. I almost would rather still have some error code to get something to work with! If anyone has any helpful suggestions/comments/links for further reading, would HUGELY appreciate it. Have read through TONS of other pages and documents to try and get this to work as simply as I want it to, but no dice so far. Thanks in advance for any help you can offer!

UPDATE on 4/20/17: I've edited the prepareForSegue function, even put in a "VCName" var in so I can call segue.destination (even though "VCName" is not used) - STILL not giving me a segue (no error msg, and its successfully building) and not sure what to try next. Any advice appreciated!

UPDATE on 4/26/17: I used some break points and found out that neither the prepare nor perform segue functions were firing. I rebuilt and made sure it was an override function of the superclass (no idea why it wouldnt let me do that before hand), and it worked! Special thanks to Sasaang for the help!


Solution

  • Your code looks good from what i can tell, and it should work with this minor change. Remember that sections and rows are indices starting at 0. You have the following:

    if (indexPath.section == 1) && (indexPath.row == 1) {
      self.performSegue(withIdentifier: "CPWSegue", sender: indexPath);
    }
    

    I suspect you are tapping on the first item in the first section and not seeing any transitions, but the code above actually refers to the second item in the second section. The "Federal Programs" cell. Change the code to the following to be able to tap the "Children and Pregnant Women" cell to segue to the next ViewController.

    if (indexPath.section == 0) && (indexPath.row == 0) {
       self.performSegue(withIdentifier: "CPWSegue", sender: indexPath);
    }
    

    Additioanlly i would suggest you save some code by adding all of your ViewController StoryBoard Id's into a similar array structure as your main title array, that way instead of many if-else statements in the didSelectRowAtIndexPath function, you can change it to simply:

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        self.performSegue(withIdentifier: identifierList[indexPath.section][indexPath.row], sender: indexPath);
    }
    

    UPDATE

    Additional note on updated question. The prepareForSegue function is just there to stage the next scene before presenting it. Like for instance if there's a "name" field in the CPW viewController, you can set it in the function like so before presenting it:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
      if segue.identifier == "CPWSegue" { 
         let nextView = segue.destination as? CPWView
         nextView.name = "SOME NAME"
      }
    }
    

    You don't call performSegue() there again, its already happening.