2013-03-23 49 views
9

我拖动2 IBActionsUIButton,一个touchDown事件,第二个拖动里面。如何在UIButton中实现两个不重叠的IBActions?

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

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

但是当我拖入里面时,touchDown动作也被触发。

如何在dragInside时禁用touchDown事件。

谢谢!

+0

只是一个猜测,做一个BOOL和两个方法检查,并通过翻转动作:' - (空) removeTarget:action:' – 2013-03-23 15:44:24

+0

您是否也希望发生相反的情况 - 也就是说,如果touchDown被触发,您是否需要dragInside不会在用户开始拖动时发生?做这项工作的唯一方法是在开始时稍微延迟一段时间,看看是否有阻力开始。如果这是不可接受的,那么你将不得不采用不同的设计。 – rdelmar 2013-03-23 17:09:31

回答

4

我已经解决了这样的问题,使用拖放事件

事件添加到您的按钮中的.xib文件或编程。

程序是:

[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]; 

那么事件的defininitons是:

- (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 
    } 

} 
+0

聪明的方式!但touchDown目标成为touchUpInside事件。 – Alex 2013-03-23 23:00:26

+0

我编辑了我的答案。 – meth 2013-03-24 07:05:13

0

我不知道它会工作,但你可以尝试

- (IBAction)dragInsideButton:(UIButton *)sender { 
    [sender removeTarget:self forSelector:@selector(clickButton:) forControlEvent:UIControlEventTouchDown]; 
} 
+0

谢谢!这是不行的,因为touchDown在拖动之前触发。 – Alex 2013-03-23 15:54:29

0

我从Two action methods for an UIButton; next track and seek forward:

更改它根据您的要求了。

就我个人而言,我只是用你的视图控制器或按钮子类中的整数跟踪按钮的状态。如果你跟踪按钮的功能,你可以控制每个动作的作用。在把一些东西,这样你的.h文件中:

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 

,然后在.m文件扔在一些这方面的东西:

@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; 

} 

之后只是链接按钮的行动,我已经在IB行动的评论中注意到了。我没有测试过,但它应该可以工作。

1

试试这个方法:

isClicked为BOOL类型的属性。设置为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; 
} 

在此之上,还可以实现removeTarget:Action:

而且,任何方法被调用先设置isClick = NO,我希望clickButton在按钮动作首先被调用。

+0

谢谢!点击按钮按钮总是先消防,我不知道如何控制。我尝试了两种,但总是有两个动作着火。 – Alex 2013-03-23 16:07:14

+0

我认为所有的操作都会被调用,一旦设置完成,你就不能停下来。有没有尝试'removeTarget:行动:'我是新来的ios,仍在学习,所以借口。 – 2013-03-23 16:10:16

+0

谢谢!如果这样做,我的touchDown事件只是双击时触发。 – Alex 2013-03-23 16:29:02

3

这种方法已经过测试,应该做我认为你正在尝试做的事情。您可以更改计时器中的延迟以获得所需的效果。我必须将3个动作连接到按钮才能使其工作 - 第三个动作是将系统重置为启动条件的touchUp。

@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; 
} 
+0

谢谢!第一次拖动就OK。点击,再拖动不起作用。接下来我需要做什么?我不知道如何控制计时器。 – Alex 2013-03-23 23:11:41

+0

您是否实现了touchUpAction方法(并将其连接到按钮)?它对我很好,反复点击和拖动。 – rdelmar 2013-03-23 23:14:57

+0

谢谢先生!我的目标touchDownAction。 – Alex 2013-03-24 00:04:07