Swift - calling self.navigationController in a custom cell class

Swift:

I have a UICollectionViewController with another file / class UICollectionViewCell

The goal is to click the UIViewController from my custom cell class.

something like that:

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

I have no problem didSelectItemAtIndexPath push from didSelectItemAtIndexPath into the UICollectionViewController , but I want to do this from the custom cell class registered in my UICollectionViewController .

When I try to click a view from a custom cell class, unfortunately, I do not have self.navigationController access

I also want to do this 100% programmatically. I do not use Storyboard or Nib files

Thanks in advance.

+5
source share
3 answers

It is a bad idea. There should not be / do such logic in the views. You must leave it with the controller (this is what MVC-Pattern is about ).

Anyway:

 class MyCollectionViewCell: UITableViewCell { var myViewController: MyViewController! } 

and when the cell is canceled, you can 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 when choosing:

 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) } 

However, I cannot imagine where this would make sense. Repeat your architecture again.

Visualize the connection of your entities by drawing it on paper. You will need to draw Models , Views, and Controllers , and only Controllers can β€œtalk” to other Controllers .

Check out this and this

+5
source

I recently came up with this question, and I have a way to demonstrate Akhilrajtr's comment, as this may help others as well.

First in your cell class you need the protocol at the top of the file:

 protocol YourCellDelegate: NSObjectProtocol{ func didPressCell(sender: Any) } 

Then in you cell class variables add this:

 var delegate:YourCellDelegate! 

When you perform an action inside your cell, activate the function of your protocol:

 func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) { delegate.didPressCell(sender: indexPath) } 

On your super primary controller, you must match the delegate you are creating:

 class MyViewController: UIViewController, YourCellDelegate{...} 

And, implement a protocol function that will fire when you click on a cell, just like you defined it before:

 func didPressCell(sender: Any){ let vc = SomeViewController() self.navigationController?.pushViewController(vc, animated: true) } 

Of course, do not forget to give a link for your delegate regarding the creation of a cell instance in the cellForItem function:

 cell.delegate = self 
+2
source

I want to expand the answer to ezcoding. Therefore instead of this code

 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 } 

You can simply use self to get the current instance of the view controller, so the code can be simplified to

 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { let cell: MyCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(myCellIdentifier, forIndexPath: indexPath) as! MyCollectionViewCell cell.myViewController = self return cell } 

This worked for me, at least in my case.

0
source

All Articles