【问题标题】:How to implement two IBActions in UIButton without overlap?如何在不重叠的情况下在 UIButton 中实现两个 IBAction?
【发布时间】:2013-03-23 15:37:27
【问题描述】:

我从 UIButton 中拖动 2 个 IBActions,一个带有 touchDown 事件,第二个带有内部拖动。

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

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

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

如何在 dragInside 时禁用 touchDown 事件。

谢谢!

【问题讨论】:

  • 只是猜测,做一个 BOOL 并检查方法并通过以下方式翻转操作:-(void)removeTarget:action:
  • 您是否还希望发生相反的情况——也就是说,如果触发了 touchDown,您是否需要在用户开始拖动时不发生 dragInside?完成这项工作的唯一方法是在开始时稍微延迟等待,看看是否开始拖拽。如果这不可接受,那么您将不得不采用不同的设计。

标签: ios objective-c uibutton ibaction


【解决方案1】:

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

在 .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];

那么事件的定义是:

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

}

【讨论】:

  • 聪明的方法!但是 touchDown 目标变成了 touchUpInside 事件。
【解决方案2】:

这个方法已经过测试,应该能做我认为你想做的事。您可以更改计时器中的延迟以获得您想要的效果。我必须将 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;
}

【讨论】:

  • 谢谢!第一次拖动就可以正常工作。单击,再次拖动不起作用。接下来我需要做什么?我不知道如何控制定时器。
  • 您是否实现了 touchUpAction 方法(并将其连接到按钮)?对我来说效果很好,反复点击和拖动。
  • 谢谢先生!我的目标 touchDownAction。
  • @Ios10,如果我的回答解决了你的问题,你应该接受。
  • 是的,先生!我需要更多时间来测试。谢谢!
【解决方案3】:

试试这个方法:

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。

【讨论】:

  • 谢谢!点击按钮按钮总是先触发,我不知道如何控制。我都尝试了,但总是 2 个动作触发。
  • 我认为所有的动作都会进入调用状态,一旦设置好就无法停止。 removeTarget:Action:你试过了吗我是ios新手,还在学习中,请见谅。
  • 谢谢!如果这样做,我的 touchDown 事件只会在双击时触发。
  • 对不起先生!不能很快回复。在我睡觉的时间。还不行。
【解决方案4】:

我来自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;
    
}

之后,只需将按钮的操作链接到我在 IBactions 之前在 cmets 中记录的内容。我没有对此进行测试,但它应该可以工作。

【讨论】:

    【解决方案5】:

    我不确定它是否会起作用,但你可以尝试

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-25
      • 1970-01-01
      • 2021-11-29
      • 1970-01-01
      • 2014-06-06
      • 1970-01-01
      • 2018-08-29
      相关资源
      最近更新 更多