6

I have a VC RaceDayChecklistViewController.m which is subclass of RaceDayChecklistViewControllerBase.m.

In RaceDayChecklistVC.m , added a target action which is getting called twice. nextOrNewButton is the button on click of which i want to invoke "demo" action. Also ,checklistnavigationItem is the bar Button item.

- (void)viewDidLoad
{
    checklistTableViewBase=checklistTableView;
   checklistNavigationItemBase=checklistnavigationItem;
    nextOrNewButtonBase=nextOrNewButton;

    [nextOrNewButton addTarget:self action:@selector(demo) forControlEvents:UIControlEventAllEvents];

}

-(void) demo
{
    RaceDayDataController *sharedController = [RaceDayDataController sharedDataController];

    if (sharedController.isSubmited)
    {
        [self.checklistnavigationItem setTitle:@"New"]; //
    }
    else
    {
        [self.checklistnavigationItem setTitle:@"Next"];
        [self showAlert];
    }
}

-(void) viewWillDisappear:(BOOL)animated
{
    [nextOrNewButton removeTarget:self action: @selector(demo) forControlEvents:UIControlEventAllEvents];
}

What could be the reason for multiple call to the action demo? Is it the base class responsible some how?

pls guide.

Lalit_vicky
  • 295
  • 1
  • 5
  • 15

4 Answers4

6

UIButton generates multiple events while pressing: usually they are UIControlEventTouchDownInside and UIControlEventTouchUpInside. So, if you want to handle press, you should catch the one you need (probably UIControlEventTouchUpInside), not UIControlEventsAll.

kovpas
  • 9,553
  • 6
  • 40
  • 44
2

I can see this

[nextOrNewButton removeTarget:self action: @selector(demo) forControlEvents:UIControlEventAllEvents];

That means, When you touch the button,touch up event(UIControlEventTouchUpInside) trigger, so it will fire one time. After that, touch down will happen, so it will fire again with UIControlEventTouchDownInside .

So you can use this,

[nextOrNewButton removeTarget:self action: @selector(demo) forControlEvents:UIControlEventTouchUpInside];
Mani
  • 17,549
  • 13
  • 79
  • 100
1

You are listening about all events, so you are getting all events.

Normally to capture the button tap event we would have UIControlEventTouchUpInside.

Here is the option for you.

        typedef NS_OPTIONS(NSUInteger, UIControlEvents) {
            UIControlEventTouchDown           = 1 <<  0,      // on all touch downs
            UIControlEventTouchDownRepeat     = 1 <<  1,      // on multiple touchdowns (tap count > 1)
            UIControlEventTouchDragInside     = 1 <<  2,
            UIControlEventTouchDragOutside    = 1 <<  3,
            UIControlEventTouchDragEnter      = 1 <<  4,
            UIControlEventTouchDragExit       = 1 <<  5,
            UIControlEventTouchUpInside       = 1 <<  6,
            UIControlEventTouchUpOutside      = 1 <<  7,
            UIControlEventTouchCancel         = 1 <<  8,

            UIControlEventValueChanged        = 1 << 12,     // sliders, etc.

            UIControlEventEditingDidBegin     = 1 << 16,     // UITextField
            UIControlEventEditingChanged      = 1 << 17,
            UIControlEventEditingDidEnd       = 1 << 18,
            UIControlEventEditingDidEndOnExit = 1 << 19,     // 'return key' ending editing

            UIControlEventAllTouchEvents      = 0x00000FFF,  // for touch events
            UIControlEventAllEditingEvents    = 0x000F0000,  // for UITextField
            UIControlEventApplicationReserved = 0x0F000000,  // range available for application use
            UIControlEventSystemReserved      = 0xF0000000,  // range reserved for internal framework use
            UIControlEventAllEvents           = 0xFFFFFFFF
        };
0

As you set UIControlEventAllEvents thats why when you touch your button it takes two type of touch so you should use only one type of Event either UIControlEventTouchUpInside or UIControlEventTouchUpOutside.

[nextOrNewButton addTarget:self action:@selector(demo) forControlEvents: UIControlEventTouchUpInside];
Tapas Pal
  • 7,073
  • 8
  • 39
  • 86