2013-03-23 5 views
9

Ich ziehe 2 IBActions von einer UIButton, eine mit TouchDown-Ereignis und Sekunde mit drag Inside.Wie implementiert man zwei IBActions in UIButton ohne Überlappung?

Aber wenn ich innen ziehe, wird auch die TouchDown-Aktion ausgelöst.

So deaktivieren Sie das Ereignis "touchDown" bei DragInside.

Danke!

+0

Nur eine Vermutung, eine BOOL machen und überprüfen sowohl in dem Verfahren und drehen Sie die Aktion durch: '- (void) removeTarget: action: ' –

+0

Möchten Sie auch, dass das Umgekehrte passiert - das heißt, wenn touchDown ausgelöst wird, brauchen Sie dragInside nicht, wenn der Benutzer anfängt zu ziehen? Die einzige Möglichkeit, dies zu erreichen, besteht darin, am Anfang mit einer geringfügigen Verzögerung zu warten, um zu sehen, ob ein Ziehen beginnt. Wenn das nicht akzeptabel ist, dann müssen Sie mit einem anderen Design gehen. – rdelmar

Antwort

4

ich habe ein Problem wie dieses mit per Drag Events

Ereignisse auf Ihre Schaltfläche in .xib Datei oder programmatisch hinzufügen gelöst.

programmatisch ist:

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

dann defininitons von Veranstaltungen sind:

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

Cleverer Weg! Aber touchDown Ziel wird zum TouchUpInside-Ereignis. – Alex

+0

Ich habe meine Antwort bearbeitet. – meth

0

ich bin nicht sicher, ob es funktionieren wird, aber Sie können

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

Danke! Es funktioniert nicht, da touchDown vor dem Ziehen ausgelöst wird. – Alex

0

versuche ich bekam von Two action methods for an UIButton; next track and seek forward:

ändern es nach Ihren Anforderungen.

Persönlich würde ich nur den Zustand der Schaltfläche mit einer Ganzzahl auf Ihrem View-Controller oder innerhalb einer Schaltfläche Unterklasse verfolgen. Wenn Sie verfolgen, was die Schaltfläche ausführt, können Sie steuern, was jede Aktion bewirkt. In Ihrer .h-Datei in ein paar Sachen so:

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 

Und dann in .m Datei wirft in etwas über dieses Thema:

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

} 

Danach verbinden nur die Aktionen der Taste zu dem, was ich habe in den Kommentaren vor den IBactions vermerkt. Ich habe das nicht getestet, aber es sollte funktionieren.

1

Versuchen Sie, diese Art und Weise:

isClicked ist Eigenschaft vom Typ BOOL. Auf YES einstellen.

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

Auf dieses können Sie auch removeTarget:Action:

implementieren, die jemals Methode zuerst isClick = NO gesetzt wird aufgerufen erwarte ich Click zuerst in Button-Aktion aufgerufen wird.

+0

Danke! Klick Knopfknopf feuern immer zuerst, ich kann nicht steuern. Ich versuche beides, aber immer 2 Action Feuer. – Alex

+0

Ich denke, alle Aktionen gehen in den Aufruf und sobald es eingestellt ist, kann man nicht aufhören. Hast du es mit 'removeTarget versucht: Action:' Ich bin neu in IOS, lerne immer noch, also entschuldige. –

+0

Danke! Wenn dies so ist, wird mein touchDown-Ereignis nur ausgelöst, wenn ein Doppelklick ausgeführt wird. – Alex

3

Diese Methode ist getestet und sollte tun, was ich denke, Sie versuchen zu tun. Sie können die Verzögerung im Timer ändern, um den gewünschten Effekt zu erzielen. Ich musste 3 Aktionen mit der Schaltfläche verbinden, damit dies funktioniert - die dritte Aktion ist ein TouchUp, das das System auf die Startbedingung zurücksetzt.

@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

Danke! Ziehen Sie einfach arbeiten OK 1. Mal. Klick, zieh wieder nicht funktioniert. Was muss ich als nächstes tun? Ich weiß nicht, wie man den Timer steuert. – Alex

+0

Haben Sie die Methode touchUpAction implementiert (und verbinden Sie sie mit der Schaltfläche)? Es hat gut für mich funktioniert, auf wiederholtes Klicken und Ziehen. – rdelmar

+0

Danke Sir! Mein Ziel ist TouchDownAction. – Alex