The iOS app I've been working recently is heavy on displaying lists of stuff, particularly lists of stuff with tap actions in the cells/views. I chose to use UICollectionViews instead of UITableViews. Similar to a UITableViewController, UICollectionViewController has a method that you need to override in order to build each list item: GetCell().

I ran into a problem with making a RESTful call from a button tap inside each cell. This is done by adding a UITapGestureRecognizer to the button or UIView in each cell. Now, because each cell's contents are reconstructed every time that it scrolls onto the screen, if you do something like:

myButton.AddGestureRecognizer(new UITapGestureRecognizer(() => {
// make a RESTful call
}));

then the gesture recognizer will be added to the button each time the cell is scrolled back onto the screen.

So, what I was seeing is that if I scrolled the item off and then back onto the screen and then I tapped the button, the RESTful call was made TWICE instead of once. If I scroll it off and on the screen three times, the RESTful call fires THRICE! I only want it fire once!

What do do???

Solution
Execute the following while loop immediately before making the AddGestureRecognizer() call:

while (myButton.GestureRecognizers != null && myButton.GestureRecognizers.Length > 0)
{
     myButton.RemoveGestureRecognizer (myButton.GestureRecognizers [0]);
}
myButton.AddGestureRecognizer(new UITapGestureRecognizer(() => {
     // make a RESTful call
}));

This will programmatically remove all the gesture recognizers each time the cell is built. Problem solved!!!

Better yet...make an extension method to do this more conveniently:

public static class UIViewExtensionMethods {
    public static void RemoveAllGestureRecognizers(this UIView view) {
    while (view.GestureRecognizers != null && view.GestureRecognizers.Length > 0)
    view.RemoveGestureRecognizer(view.GestureRecognizers[0];
    }
}

...and call it like this:

myButton.RemoveAllGestureRecognizers();
myButton.AddGestureRecognizer(new UITapGestureRecognizer(() => {
// make a RESTful call
}));