Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement two IBActions in UIButton without overlap?

I drag 2 IBActions from a UIButton, one with touchDown event and second with drag Inside.

- (IBAction)clickButton:(UIButton *)sender {
    NSLog(@"Click Button");
}

- (IBAction)dragInsideButton:(UIButton *)sender {
    NSLog(@"Drag Button");
}

But when I drag inside, the touchDown action also gets fired.

How to disable touchDown event when dragInside.

Thanks!

like image 314
Alex Avatar asked Mar 23 '13 15:03

Alex


3 Answers

i have solved a problem like this with using drag Events

add events to your button in .xib file or programatically.

programmatically is:

[mybut addTarget:self action:@selector(dragBegan:withEvent: )
  forControlEvents: UIControlEventTouchDown];
    [mybut addTarget:self action:@selector(dragMoving:withEvent: )
  forControlEvents: UIControlEventTouchDragInside];
    [mybut addTarget:self action:@selector(dragEnded:withEvent: )
  forControlEvents: UIControlEventTouchUpInside |
     UIControlEventTouchUpOutside];

then defininitons of events are:

- (void) dragBegan: (UIButton *) c withEvent:ev
{
    NSLog(@"dragBegan......");
    count=NO;//bool Value to decide the Down Event
    c.tag=0;
  [self performSelector:@selector(DownSelected:) withObject:mybut afterDelay:0.1];
 //user must begin dragging in 0.1 second else touchDownEvent happens

}

- (void) dragMoving: (UIButton *) c withEvent:ev
{
    NSLog(@"dragMoving..............");
    c.tag++;
}

- (void) dragEnded: (UIButton *) c withEvent:ev
{
    NSLog(@"dragEnded..............");
    if (c.tag>0 && !count)
    {

        NSLog(@"make drag events");

    }

}



-(void)DownSelected:(UIButton *)c
{
    if (c.tag==0) {
        NSLog(@"DownEvent");
        count=YES;//count made Yes To interrupt drag event
    }

}
like image 106
meth Avatar answered Nov 16 '22 16:11

meth


This method is tested, and should do what I think you're trying to do. You can change the delay in the timer to get the effect you want. I had to connect 3 actions to the button to make this work -- the third action is a touchUp that resets the system to the starting condition.

@interface LastViewController ()
@property (nonatomic) BOOL touchedDown;
@property (strong,nonatomic) NSTimer *downTimer;
@end

@implementation LastViewController 

- (void)viewDidLoad {
    [super viewDidLoad];
    self.touchedDown = NO;
}

-(IBAction)clickDown:(id)sender {
    self.downTimer = [NSTimer scheduledTimerWithTimeInterval:.3 target:self selector:@selector(buttonAction:) userInfo:nil repeats:NO];
}

-(IBAction)dragInside:(id)sender {
    [self.downTimer invalidate];
    [self buttonAction:self];
}


-(void) buttonAction:(id) sender {
    if ([sender isKindOfClass:[NSTimer class]]) {
        self.touchedDown = YES;
        NSLog(@"click down");
    }else{
        if (! self.touchedDown) {
             NSLog(@"Drag");
        }
    }
}

-(IBAction)touchUpAction:(id)sender {
    self.touchedDown = NO;
}
like image 26
rdelmar Avatar answered Nov 16 '22 16:11

rdelmar


Try this way:

isClicked is property of type BOOL. Set to YES.

- (IBAction)clickButton:(UIButton *)sender { //touch down
    if(isClick==YES){
       NSLog(@"Click Button");
       //do all your stuffs here
    }
    isClick=YES;
}

- (IBAction)dragInsideButton:(UIButton *)sender {
    NSLog(@"Drag Button");
    isClick=NO;
}

On top of this you can also implement removeTarget:Action:

Which ever method gets called first set isClick=NO, I expect clickButton is called first in button action.

like image 1
Anoop Vaidya Avatar answered Nov 16 '22 15:11

Anoop Vaidya