Monotouch TouchUpInside does not work, TouchDown works

3.7k views Asked by At

I have seen some topics about this subject in Objective-C. I read a lot of them, spent 2 days on it on trying to find a solution and none of them worked for me. I am mainly coding in C#. Since my problem behaviour (fire only when leaving/re-enter button) and context (C#) is a bit different. So, I will try my chance by asking my question here.

I will try to keep it simple.

Here is a sample of code:

private UIButton _buttonTest;

public override void ViewDidLoad ()
{
    base.ViewDidLoad ();

    _buttonTest = new UIButton(new RectangleF(10, 70, 50, 50));
    _buttonTest.SetTitle("0", UIControlState.Normal);
    _buttonTest.TouchUpInside += HandleButtonTestTouchUpInside;
    _buttonTest.BackgroundColor = UIColor.Red;
    this.View.AddSubview(_buttonTest);
}

void HandleButtonTestTouchUpInside (object sender, EventArgs e)
{
    string textNumber = _buttonTest.Title(UIControlState.Normal);

    // Increment Number
    _buttonTest.SetTitle((int.Parse(textNumber)+1).ToString(), UIControlState.Normal);
}
  • There is a button and the title text is set to "0".
  • When the user click on it, it increments the number (title) by 1.

This code usually works very well!

However, it does not work in some of my classes for some unknown reasons...

Here is the problem:

  • TouchUpInside does not fire. ... However, if I hold the button with a finger and keep holding the finger while leaving the button and then re-entering the button then release the button, then.... it will fire the TouchUpInside, .... so the finger need to leave and re-renter the button while holding the button to make the TouchUpInside fires. Usually, this code works very well.

Things Checked:

  • if I replace TouchUpInside by TouchDown, then TouchDown works.
  • 'User Interaction Enabled' is set to True for all superviews.
  • All views frames (among the superviews) seem to be inside their superview frames.
  • I moved the _buttonTest around and I noticed that the _buttonTest TouchUpInside does not fire correctly in the View, the SuperView, the SuperSuperView.... but it fires correctly in the SuperSuperSuperView.

Any suggestion?

2

There are 2 answers

1
Patrick Simard On BEST ANSWER

In the SuperSuperView, I had this tap gesture that was entering in conflict with the Button event.

    // Tap Gesture
    UITapGestureRecognizer tapPageGestureRecognizer = new UITapGestureRecognizer();
    tapPageGestureRecognizer.AddTarget(this, new Selector ("HandleTapPageGestureRecognizer:"));         
    this.View.AddGestureRecognizer(tapPageGestureRecognizer);

The idea is to disable the gesture SuperSuperView gesture when the button event, TouchDown was fired, ... and to re-enable it when the TouchUpInside is fired.

So here is one solution for the problem:

private void SetGrandParentViewGestureEnabled(bool enabled)
{
    foreach(UIGestureRecognizer g in this.View.Superview.Superview.GestureRecognizers)
    {
        g.Enabled = enabled;
    }
}

void HandleButtonSubmitTouchDown (object sender, EventArgs e)
{
    SetGrandParentViewGestureEnabled(false);
}

void HandleButtonSubmitTouchUpInside (object sender, EventArgs e)
{
    // => Do treatments here!

    SetGrandParentViewGestureEnabled(true);
}

However, I could have used EventHandler or Action to enable/disable the tap gesture.

EDIT: Here is another function that need to be added as well to re-enable the gesture.

void HandleButtonSubmitTouchUpOutside (object sender, EventArgs e)
{
    SetGrandParentViewGestureEnabled(true);
}
0
Bjarke On

I had a similar problem, I ended up using a tap recognizer together with the long press recognizer like this for the button TopRightButton.

     var longPressGesture = new UILongPressGestureRecognizer(Action);
            TopRightButton.AddGestureRecognizer(longPressGesture);

            var tapRecognizer = new UITapGestureRecognizer();

            tapRecognizer.AddTarget(() =>
                                    {
            //method
            });

            tapRecognizer.NumberOfTapsRequired = 1;

            this.TopRightButton.AddGestureRecognizer(tapRecognizer); 
private void Action(){  };