Как реализовать два IBActions в UIButton без перекрытия?

Я перетаскиваю 2 IBActions из UIButton, один с событием touchDown, а второй с перетаскиванием внутрь.

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

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

Но когда я перетаскиваю внутрь, также срабатывает действие touchDown.

Как отключить событие touchDown при dragInside.

Спасибо!


person Alex    schedule 23.03.2013    source источник
comment
Просто предположение, сделайте BOOL и проверьте оба метода и переверните действие: -(void)removeTarget:action:   -  person Anoop Vaidya    schedule 23.03.2013
comment
Вы также хотите, чтобы произошло обратное, то есть, если touchDown запущен, вам нужно, чтобы dragInside не происходило, если пользователь начинает перетаскивание? Единственный способ заставить эту работу работать — с небольшой задержкой в ​​​​начале подождать и посмотреть, не начнется ли перетаскивание. Если это неприемлемо, вам придется использовать другой дизайн.   -  person rdelmar    schedule 23.03.2013


Ответы (5)


я решил подобную проблему с помощью событий перетаскивания

добавить события к вашей кнопке в файле .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
    }

}
person meth    schedule 23.03.2013
comment
Умный способ! Но цель touchDown становится событием touchUpInside. - person Alex; 24.03.2013

Этот метод проверен и должен делать то, что, как я думаю, вы пытаетесь сделать. Вы можете изменить задержку в таймере, чтобы получить желаемый эффект. Мне пришлось привязать к кнопке 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;
}
person rdelmar    schedule 23.03.2013
comment
Спасибо! Перетащите просто работать нормально 1-й раз. нажмите, перетащите снова не работает. Что мне нужно делать дальше? Я не знаю, как управлять таймером. - person Alex; 24.03.2013
comment
Вы реализовали метод touchUpAction (и подключили его к кнопке)? У меня это работало нормально, при повторном щелчке и перетаскивании. - person rdelmar; 24.03.2013
comment
Спасибо, сэр! Моя цель touchDownAction. - person Alex; 24.03.2013
comment
@ iOS10, если мой ответ решил вашу проблему, вы должны принять его. - person rdelmar; 24.03.2013
comment
Да сэр! Мне нужно больше времени для проверки. Спасибо! - person Alex; 24.03.2013

Попробуйте так:

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 будет вызываться первым в действии кнопки.

person Anoop Vaidya    schedule 23.03.2013
comment
Спасибо! Нажмите кнопку всегда срабатывает первой, я не знаю, как управлять. Я пробую оба, но всегда 2 действия стреляют. - person Alex; 23.03.2013
comment
я думаю, что все действия переходят в вызов, и как только он установлен, вы не можете остановиться. Вы пробовали removeTarget:Action: Я новичок в ios, все еще учусь, так что извините. - person Anoop Vaidya; 23.03.2013
comment
Спасибо! Если это так, событие My touchDown просто срабатывает при двойном щелчке. - person Alex; 23.03.2013
comment
Извините, сэр! Не могу ответить в ближайшее время. Пора спать. Еще не все в порядке. - person Alex; 24.03.2013

Я получил от два метода действий для UIButton; следующий трек и переход вперед:

Измените его в соответствии с вашим требованием.

Лично я бы просто отслеживал состояние кнопки с целым числом на вашем контроллере представления или в подклассе кнопки. Если вы отслеживаете, что делает кнопка, вы можете контролировать, что делает каждое из действий. В вашем файле .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. Я не тестировал это, но это должно работать.

person iPatel    schedule 23.03.2013

я не уверен, что это сработает, но вы можете попробовать

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