1

How to add didSelectRowAt action to the tableview inside a table View cell [Swift]? When I'm trying to open another view controller,I'm unable to declare the storyboard even..

enter image description here I had a table view inside a table view cell.The action on selecting a row of the table view inside the table view cell needs to be same as that of the didSelectRowAt() of the parent table view's cell.The actual didSelectRowAt() of the parent table view cell navigates to another view controller.So I'm trying to call the view controller,but unable to do so...Is there any other way around this issue...

Nancy
  • 158
  • 2
  • 11
  • Don't put screen shot copy and paste code in question – Prashant Tukadiya Feb 22 '18 at 12:17
  • In which class you have added delegate method ? Make sure it is subclass of UIViewController if you want to access self.storyboard property – Prashant Tukadiya Feb 22 '18 at 12:18
  • Possible duplicate of [Instantiate and Present a viewController in Swift](https://stackoverflow.com/questions/24035984/instantiate-and-present-a-viewcontroller-in-swift) – Prashant Tukadiya Feb 22 '18 at 12:20
  • In order to use storyboard, You have to declare it first right? –  Feb 22 '18 at 12:29
  • let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main) –  Feb 22 '18 at 12:29
  • You wrote: "tableview inside a table View cell"; just to be sure, do you have a tableView inside a cell ? Please clarify and share some more code. – koen Feb 22 '18 at 13:15

5 Answers5

1

TableViewCell cannot present a ViewController,

If your tableViewCell contain another tableView, and you click on one of its cell, you have to inform your ViewController that the cell was pressed

Put this in your tableview cell (which is inside another table view cell) didSelectRowAt method

NotificationCenter.default.post(name: Notification.Name("aNotificationName"), object: nil)

Add observer in you viewController viewDidLoad method

NotificationCenter.default.addObserver(self, selector: #selector(handleNotificationFuncName, name: NSNotification.Name(rawValue: "aNotificationName"), object: nil)

And handle your notification here

func handleNotificationFuncName(_ notification: Notification) {
    let storyboard = UIStoryboard(name: "StoryboardName", bundle: Bundle.main)

    if let vc = storyboard.instantiateViewController(withIdentifier: "pdfDisplayViewController") as? pdfDisplayViewController {
        present(vc, animated: true, completion: nil)
    }
}
zheck
  • 298
  • 3
  • 11
  • Thanks.. it helped a lot...Disabling User interaction in the storyboard over the table view helped me when I faced the same kind of issue again.. – Nancy Mar 07 '18 at 12:04
0

You can try this:

let storyboard = UIStoryboard(name: "StoryboardName", bundle: Bundle.main)
if let vc = let vc = storyboard.instantiateViewController(withIdentifier: "pdfDisplayViewController") as? pdfDisplayViewController {

        ///do stuff here
}

Hope it helps!!

Agent Smith
  • 2,873
  • 17
  • 32
0

Looks like you've declared your cell class itself as the tableView's delegate, instead make your current ViewController conform to UITableViewDelegate and then instantiate the view controller and push it on to the stack:

class MyViewController: UITableViewDelegate {

    ..

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "pdfdisplayviewcontroller") as? pdfdisplayViewController {
            navigationController.pushViewController(controller, animated: true)
        }
    } 

    ..
}
justintime
  • 352
  • 3
  • 11
0

You can use following code to navigate from one ViewController to another ViewController.

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

            let storyboard = UIStoryboard(name: "YourStoryBoardName", bundle: nil)
            let controller = storyboard.instantiateViewController(withIdentifier: "pdfDisplayViewController") as! pdfDisplayViewController
            self.navigationController?.pushViewController(controller, animated: false)
            self.navigationController?.navigationBar.isHidden = true
        }

But your issue is different i think so update your question.

Ram
  • 858
  • 1
  • 14
  • 19
0

It is not a best practice to navigate to another ViewController or perform any interation from the tableView Cells. I prefer you to use delegate pattern to get the desired feature.

  1. Declare a weak delegate in the tableview cell. a. send the payload. i,e (indexpath of selected cell) to the viewController.
  2. Perform action there in the viewController.

Notification can also be used for the same however they are usually discouraged and we should try to use them in rare cases.

protocol InnerTableCellDelegate: class {
   func didSelectedRowWith(indexPath: IndexPath)
}
class InnerTableCell: UITableViewCell {

weak var delegate: InnerTableCellDelegate? = nil 
 .
 .
 . 
     // In tableCellDelegate
     func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
       if let safeDelegate = self.delegate {
           safeDelegate.didSelectedRowWith(indexPath: indexPath)
        }     
     }
  }  

Now you must be having same tableView delegates and datasource in the parent viewController. There in the cellForRowAt(...) method set the cell delegate as self.

class ViewController: UIViewController {
  // MARK: - TableView Datasouce & Delegates
  func cellForRowAt(tableView: UITableView, indexPath: IndexPath) -> UITableViewCell {
     let cell: InnerTableCell = tableView.dequeReusableCellWithIdentifier(reusableIdentifier: "InnerTableViewCell", indexPath: IndexPath) as! InnerTableViewCell
     cell.delegate = self
     return cell
  }
} 

Now, conform you viewcontroller to the cell delegate and perform action from there.

extension ViewController: InnerTableCellDelegate {
    func didSelectedRowWith(indexPath: IndexPath) {
       let storyboard = UIStoryboard(name: "storyboard", bundle: nil)
       let viewC = storyboard.instantiateViewController(withIdentifier: "DestinationViewC") as! DestinationViewC
       self.navigationController?.pushViewController(controller, animated: false)
      }
    } 
Peeyush karnwal
  • 622
  • 7
  • 24