'Perform a segue by clicking a button in a custom UICollectionViewCell

I'm trying to understand what is the correct way to perform a segue by clicking a button in a custom UICollectionViewCell (I'm using a storyboard to create the screens of the app).

I have a view controller which holds a UICollectionView:

    MyDataSource myDataSource = new MyDataSource(listOfItems);
     
    myCollectionView.Source = myDataSource;

MyDataSource is a subclass of UICollectionViewSource

     public override UICollectionViewCell GetCell(UICollectionView collectionView, Foundation.NSIndexPath indexPath)
     {
            MyCustomCell customListCell = (MyCustomCell)collectionView.DequeueReusableCell("listCell", indexPath);
            customListCell.updateItem(indexPath.Row);
            return customListCell;
     }

MyCustomCell updateItem method updates the cell's properties and also wires TouchUpInside event for the button:

    public void updateItem(int index)
    { 
         myButton.TouchUpInside += (sender, e) =>
         {
            /* NOW I WANT TO PERFORM THE SEGUE 
               AND PASS THE INDEX THAT WAS CLICKED */
         };  
    }

After reading some old questions a few solutions were suggested, which I'm trying to avoid:

  1. Pass a reference to the parent ViewController and use this reference to perform the segue.

  2. Create a segue in the storyboard and when the user clicks the button save a static value of the selection which can be accessed from the next ViewController.

Seems to me that these two solutions are more of a workaround and using Events is the correct path, but I'm not sure regarding the implementation.

So for example I will create an EventHandler in MyCustomCell:

public event EventHandler<MyDataType> ButtonClicked;

Then in TouchUpInside:

    myButton.TouchUpInside += (sender, e) =>
    {
             ButtonClicked(this, MyDataType);
    };

But for this to work I will need to use this event in the parent view controller:

   MyCustomCell.ButtonClicked += (sender, e) =>
   {
                PerformSegue("theSegueIdentifier", this);
   };

I don't have any reference to MyCustomCell in the parent view controller, so how can I use this event in the parent view controller?



Solution 1:[1]

How about this:

VC:

MyDataSource myDataSource = new MyDataSource(listOfItems,CurrentVC);?

DataSource:

this.currentVC = CurrentVC;

myButton.TouchUpInside += (sender, e) =>
{

     currentVC.PerformSegue("theSegueIdentifier", this);
     //currentVC is the instance of current controller  
};

Better recommend to try this to navigation ,then not need to create Segue related to Button for each cell:

NextViewController nextController = this.Storyboard.InstantiateViewController ("NextViewController") as NextViewController ;
if (nextController != null) {     
     this.NavigationController.PushViewController (nextController, true);
}

Solution 2:[2]

You can add another EventHandler "buttonClicked2" in your datasource class "MyDataSource", and do this:

MyCustomCell.ButtonClicked += (sender, e) =>
{
            //PerformSegue("theSegueIdentifier", this);
            //instead of perform segue, you raise the event
            buttonClicked2();
};

Then you can fill in the rest.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 ouflak