3

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?

Patrick Simard
  • 113
  • 1
  • 8
  • Have you tried the Monotouch Community for assistance? Perhaps your missing a trick or simply are using the wrong event. The fact your using `TouchUpInside` indicate the event will happen after `Touchdown` its not clear you actually know this. – Security Hound Jul 31 '12 at 17:09
  • 1
    I use `TouchUpInside` for all button clicks (so this is the right approach), and have not had issues like you mention. Are other views on top of your button that would prevent it from being clicked? – jonathanpeppers Jul 31 '12 at 17:14
  • I did not try Monotouch Community yet but perhaps I will soon. I hope I am missing a trick but I think I am using the right Event. Yeah I know that the TouchUpInside event appear after a TouchDown. – Patrick Simard Jul 31 '12 at 17:19
  • I use TouchUpInside often also but it's the first time I have this kind of issue. ... I will check if there is not another view on top of my button that will prevent it from being clicked.... – Patrick Simard Jul 31 '12 at 17:25
  • 2
    Ok, I think I found the problem, ... there is a conflict between the button and the tap gesture I declared in the SuperSuperView. So since the tap gesture is fired on the grandfather view, it seems it cancel the TouchUpInside in the button. I will try to find an elegant solution... otherwise, ... I will have to disable the tap gesture in the TouchDown, ... then re-enable the gesture in the TouchUpInside. – Patrick Simard Jul 31 '12 at 18:10
  • I could definitely see a gesture recognizer messing up the button's event. Is there a way to avoid using it on the other view? Maybe just make the parent view a button, etc.? – jonathanpeppers Jul 31 '12 at 19:27
  • Actually, seems this is the problem (with gesture recognizers). However, the "funniest" thing is that this works well in Simulator for me, but not on real device! – Agat Jul 06 '13 at 18:30
  • For me it fails in iOS 5.0 simulator and iOS 5.0 iPad, but works on iOS 6 iPhone/iPad (and Simulator IIRC) – Jared Thirsk Jul 15 '13 at 19:02

2 Answers2

2

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);
}
Patrick Simard
  • 113
  • 1
  • 8
  • Thank you! I am glad I stumbled across this. For me, it works in iOS6 but not iOS 5. BTW, lambdas can make for cleaner code. e.g.: myButton.TouchDown += (object sender, EventArgs e) => myGesture.Enabled = false; – Jared Thirsk Jul 15 '13 at 18:52
0

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(){  };
Bjarke
  • 1,283
  • 11
  • 36