Arinjay
Arinjay

Reputation: 69

Navigate to view controller from Tableview cell inside collectionview

So I have tableview embedded in collectionview. I have xib for tableview. When user select a cell of tableview I want to navigate to another view controller.

I tried this method but its not working

let storyboardId = "Login"
        let vc = storyboard?.instantiateViewController(withIdentifier: storyboardId) 
        navigationController?.pushViewController(vc!, animated: true)

But its not working because this viewcontroller in not added to navigation stack.

    class DetailCollectionViewCell: UICollectionViewCell, UITableViewDelegate,UITableViewDataSource {


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

//        let navigationController = UINavigationController()
//        let storyboardId = "Login"
//        let vc = storyboard?.instantiateViewController(withIdentifier: storyboardId)
//        navigationController?.pushViewController(vc!, animated: true)


    }

}

How do i solve this problem. Any help is appreciated.

Upvotes: 2

Views: 4057

Answers (3)

Rahul Umap
Rahul Umap

Reputation: 2859

You can solve this problem by using a delegation pattern use the following steps :

  • Confirm table view delegate to the collection view and collection view delegate to the respective view controller.
  • delegation chaining can be used to solve this problem. In this example, I have shown how you can pass data from table view cell to collection view cell.
  • Implement collection view delegate and data source methods.
  • Implement table view delegate and data source methods.
  • whenever did select row will get called the call delegate method to tell view controller that some row is selected and according to the row index change handle your navigation.

code example:

  • Step 1: Create a protocol.

    protocol RowSelected : class {
     func rowSelected(_ index : Int)
    }
    
  • Step 2: Declare delegate variable in TableViewCell.

    weak var delegate: RowSelected?
    
  • Step 3: In collection view confirm delegate and Implement delegated method.

      let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellIdentifier", for: indexPath) as! CollectionViewCell
      cell.delegate = self
      return cell
    
      extension CollectionViewCell : RowSelected {
         func rowSelected() {
          // Pass the information to view controller via a delegate/closure/notification. just like we passed information from table view cell to collection view cell and handle navigation accordingly.
         }
      }
    
  • Step 4: In ViewController you can confirm a delegate for collection view and implement it's delegate method and can handle navigation.

You can use a closure and notification center as well to inform view controller to navigate to next screen.

Upvotes: 0

Prashant Tukadiya
Prashant Tukadiya

Reputation: 16436

You have following options

1) Implement tableview datasource and delgate in viewController instead of collection view cell
2) Use Delegate (explained below )
3) Use Closures
4) Use NotificationCenter

You need to create delegate or protocol as collection view cell can't push or present view controller.

Here is simple example (This is not exact code you may need modification)

Create protocol

protocol TableViewInsideCollectionViewDelegate:class {
    func cellTaped(data:IndexPath)
}

Inside your collectionview cell add weak property

weak var delegate:TableViewInsideCollectionViewDelegate?

Now in your ViewController class you in cellForItem method of collectionview you need to set delegate to self

like

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YourCell", for: indexPath) as! CustomCollectionCell
    cell.delegate = self
    return cell

and implement delegate method in viewController class and write code to push your view controller from there like self.navigationController.push

Now In Goto Collectionview Cell method

and whenever your tableviewDidSelect called

call delegate method like self.delegate?.cellTaped(data: dataYouWantToPass)

Hope it is helpful

Upvotes: 4

Zorot
Zorot

Reputation: 31

You have to check some info:

  • First: Check your navigationController is nil or not
  • Second: Check your initial view controller method is correct or not, this is my way:

    let storyboard = UIStoryboard(name: "Main", bundle: nil)

    let viewController = storyboard.instantiateViewController(withIdentifier: "StoryboardIdentifier") as? ViewController

enter image description here

Upvotes: 0

Related Questions