Search code examples
iosswiftuicollectionviewcell

Swift - Call self.navigationController into custom cell class


Swift:

I have UICollectionViewController with another file/class UICollectionViewCell

The goal is to push UIViewController from my custom cell class.

something like this:

self.navigationController?.pushViewController(vc, animated: true)

I have no problems to implement push from didSelectItemAtIndexPath in UICollectionViewController but i want to do this from custom cell class registered into my UICollectionViewController.

When i try to push view from custom cell class unfortunately i don't have access self.navigationController

Also i want to do this 100% programmatically. I don't use Storyboard or Nib files

Thanks in advance.


Solution

  • This is a bad idea. Views should not have/do that kind of logic. You should leave it with the Controller (that's what the MVC-Pattern is about).

    Anyway:

    class MyCollectionViewCell: UITableViewCell {
        var myViewController: MyViewController!
    }
    

    and when the cell is dequeued you could set it like this:

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
    {
        let cell: MyCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(myCellIdentifier, forIndexPath: indexPath) as! MyCollectionViewCell
        let nvc: UINavigationController = UIStoryboard(name: "myStoryboard", bundle: nil).instantiateViewControllerWithIdentifier("myNavigationController") as! UINavigationController
        cell.myViewController = nvc.childViewControllers.first as! MyViewController
    
        return cell
    }
    

    and on selection:

    func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
    {
        let cell: MyCollectionViewCell = collectionView.cellForItemAtIndexPath(indexPath) as! MyCollectionViewCell
    
        // I don't know where vc comes from
        cell.myViewController.navigationController?.pushViewController(vc, animated: true)
    }
    

    Still, there is no case I can think of, where this would make any sense. So rethink your architecture again.

    Visualize the communication of your entities, by drawing it on a paper. You'll have to draw Models, Views and Controllers and only Controllers are allowed to "talk" to other Controllers.

    Look at this and this