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!
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
}
}
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;
}
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.
I got from Two action methods for an UIButton; next track and seek forward:
Change it As per your requirement.
Personally I'd just track the button's state with an integer on your view controller or within a button subclass. If you track what the button is doing you can control what each of the actions do. In your .h file put in some stuff like this:
enum {
MyButtonScanning,
MyButtonStalling,
MyButtonIdle
};
@interface YourClass : UIViewController {
NSInteger buttonModeAt;
}
@property (nonatomic) NSInteger buttonModeAt;
-(IBAction)buttonPushedDown:(id)sender;
-(void)tryScanForward:(id)sender;
-(IBAction)buttonReleasedOutside:(id)sender;
-(IBAction)buttonReleasedInside:(id)sender;
@end
And then in your .m file throw in some of this stuff:
@implementation YourClass
///in your .m file
@synthesize buttonModeAt;
///link this to your button's touch down
-(IBAction)buttonPushedDown:(id)sender {
buttonModeAt = MyButtonStalling;
[self performSelector:@selector(tryScanForward:) withObject:nil afterDelay:1.0];
}
-(void)tryScanForward:(id)sender {
if (buttonModeAt == MyButtonStalling) {
///the button was not released so let's start scanning
buttonModeAt = MyButtonScanning;
////your actual scanning code or a call to it can go here
[self startScanForward];
}
}
////you will link this to the button's touch up outside
-(IBAction)buttonReleasedOutside:(id)sender {
if (buttonModeAt == MyButtonScanning) {
///they released the button and stopped scanning forward
[self stopScanForward];
} else if (buttonModeAt == MyButtonStalling) {
///they released the button before the delay period finished
///but it was outside, so we do nothing
}
self.buttonModeAt = MyButtonIdle;
}
////you will link this to the button's touch up inside
-(IBAction)buttonReleasedInside:(id)sender {
if (buttonModeAt == MyButtonScanning) {
///they released the button and stopped scanning forward
[self stopScanForward];
} else if (buttonModeAt == MyButtonStalling) {
///they released the button before the delay period finished so we skip forward
[self skipForward];
}
self.buttonModeAt = MyButtonIdle;
}
After that just link the button's actions to what I've noted in the comments before the IBactions. I haven't tested this but it should work.
i'm not sure it will work but you can try
- (IBAction)dragInsideButton:(UIButton *)sender {
[sender removeTarget:self forSelector:@selector(clickButton:) forControlEvent:UIControlEventTouchDown];
}