jub
jub

Reputation: 43

Swipe gestures fires twice

I'm developing an application for the Ipad using Monotouch (5.0.4). I have a problem with swipe gestures which I hope someone can help me with, where the swipe gestures calls my target delegate twice.

The specific case is this: In my UINavigationController, I push the first UIViewController (which is then the root) in the overridden method ViewDidLoad. In this view controller, I register a swipe gesture (left), which in its target delegate pushes a new view controller in the navigation controller. This works, also with multiple pushes of different view controllers. However, after the first view controller has been pushed, right swipe gestures (which pops a view controller) calls their delegate twice, and two view controllers are popped. This does not happen in the root view controller.

I've made an isolated test of the problem in this simple class. What it does is to register two swipe recognizers for left and right swipes. Left swipes pushes a new instance of the same view controller, and right swipes pops it. I have tried using selectors instead of NSAction delegates as well, with the same result.

    public class SwipeTest : UIViewController
{
    public override void LoadView ()
    {
        base.LoadView ();

        // Create left swipe recognizer
        UISwipeGestureRecognizer leftRecognizer = new UISwipeGestureRecognizer ();
        leftRecognizer.Direction = UISwipeGestureRecognizerDirection.Left;
        leftRecognizer.Delegate = new UIGestureRecognizerDelegate ();
        leftRecognizer.AddTarget (new NSAction (OnSwipeLeft));
        View.AddGestureRecognizer (leftRecognizer);

        // Create right swipe recognizer
        UISwipeGestureRecognizer rightRecognizer = new UISwipeGestureRecognizer ();
        rightRecognizer.Direction = UISwipeGestureRecognizerDirection.Right;
        rightRecognizer.Delegate = new UIGestureRecognizerDelegate ();
        rightRecognizer.AddTarget (new NSAction (OnSwipeRight));
        View.AddGestureRecognizer (rightRecognizer);
    }

    public override void ViewWillDisappear (bool animated)
    {
        base.ViewWillDisappear (animated);
    }

    private void OnSwipeLeft ()
    {
        Console.WriteLine ("swipe left");

        NavigationManager.Instance.PushViewController (new SwipeTest (), true);
    }

    private void OnSwipeRight ()
    {
        Console.WriteLine ("swipe right");

        NavigationManager.Instance.PopViewControllerAnimated (true);
    }
}

NavigationManager is my UINavigationController, it is a singleton, but doesn't do much else.

    public class NavigationManager : UINavigationController
{
    #region Singleton

    class Nested
    {
        static Nested () {}

        internal static readonly NavigationManager instance = new NavigationManager();
    }

    public static NavigationManager Instance
    {
        get { return Nested.instance; }
    }

    #endregion

    #region Private fields

    private UIViewController firstController;

    private UIViewController root;

    #endregion

    #region Constructor

    private NavigationManager ()
    {
        // Set first view
        //firstController = new InitializationView ();
        firstController = new SwipeTest ();
    }

    #endregion

    #region Methods

    public override void ViewDidLoad ()
    {
        PushViewController (firstController, false);

        base.ViewDidLoad ();
    }

    #endregion

    #region Properties

    public UIViewController RootController
    {
        get {
            return root;
        }
        set {
            root = value;

            ViewControllers = new UIViewController[1] {value};
        }
    }

    #endregion
}

So, to recap: Left swipes (pushing a view controller) works, right swipes (popping a view controller) works the first time while at the root controller (so it doesn't actually do anything), but after a view controller has been pushed (after the root controller), right swipes calls the delegate twice.

I hope someone has an idea as to why this happens, I have run out of things with my knowledge of Monotouch to try.

Upvotes: 0

Views: 1140

Answers (1)

Chuck Savage
Chuck Savage

Reputation: 11955

You've probably long since figured this out, but here is a handy Swipe extension method that I came up with.

In LoadView call:

View.Swipe(UISwipeGestureRecognizerDirection.Right).Event += (s, r) =>
    new UIAlertView("Swipe Test", "Swipe " + r.Direction.ToString(), null, "Ok")
        .Show();

Upvotes: 2

Related Questions