2013-03-23 34 views
9

Tôi kéo 2 IBActions từ một UIButton, một với sự kiện touchDown và thứ hai với kéo Bên trong.Làm cách nào để triển khai hai IBActions trong UIButton mà không bị chồng chéo?

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

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

Nhưng khi tôi kéo bên trong, hành động chạm cũng được kích hoạt.

Cách tắt sự kiện touchDown khi dragInside.

Cảm ơn!

+0

Chỉ cần một đoán, làm cho một BOOL và kiểm tra trong cả hai phương pháp này và lật hành động bằng cách: '- (void) removeTarget: action: ' –

+0

Bạn cũng muốn điều ngược lại xảy ra - có nghĩa là, nếu touchDown được kích hoạt, bạn có cần dragInside không xảy ra nếu người dùng bắt đầu kéo không? Cách duy nhất để làm cho công việc này là có được với một sự chậm trễ nhỏ ở đầu để chờ đợi và xem một kéo bắt đầu. Nếu điều đó không được chấp nhận, thì bạn sẽ phải đi với một thiết kế khác. – rdelmar

Trả lời

4

tôi đã giải quyết được một vấn đề như thế này với công cụ drag Sự kiện

thêm sự kiện vào nút của bạn trong tập tin .xib hoặc chương trình khác.

lập trình là:

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

sau đó defininitons các sự kiện là:

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

Cách thông minh! Nhưng mục tiêu touchDown trở thành sự kiện touchUpInside. – Alex

+0

tôi đã chỉnh sửa câu trả lời của mình. – meth

0

tôi không chắc chắn nó sẽ làm việc nhưng bạn có thể thử

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

Cảm ơn! Nó không hoạt động bởi vì touchDown cháy trước khi kéo. – Alex

0

tôi nhận được từ Two action methods for an UIButton; next track and seek forward:

Thay đổi nó Theo yêu cầu của bạn.

Cá nhân tôi chỉ cần theo dõi trạng thái của nút bằng số nguyên trên bộ điều khiển chế độ xem của bạn hoặc trong một lớp con nút. Nếu bạn theo dõi những gì nút đang làm bạn có thể kiểm soát những gì mỗi hành động làm. Trong file .h của bạn đưa vào một số nội dung như thế này:

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 

Và sau đó trong tập tin ném .m bạn trong một số các công cụ này:

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

} 

Sau đó chỉ liên kết hành động của nút với những gì tôi đã ghi nhận trong các ý kiến ​​trước khi các IBactions. Tôi đã không thử nghiệm này nhưng nó sẽ làm việc.

1

Hãy thử cách này:

isClicked là tài sản thuộc loại BOOL. Đặt thành 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; 
} 

Ngày đầu này, bạn cũng có thể thực hiện removeTarget:Action:

Trong đó bao giờ phương pháp được gọi là đầu tiên thiết lập isClick = NO, tôi mong đợi clickButton được gọi là đầu tiên trong button action.

+0

Cảm ơn! Nút bấm nút luôn kích hoạt trước, tôi không biết cách điều khiển. Tôi cố gắng cả hai, nhưng luôn luôn 2 hành động cháy. – Alex

+0

tôi nghĩ rằng tất cả các hành động đi vào yêu cầu và một khi nó được thiết lập bạn không thể dừng lại. Có yuo cố gắng bởi 'removeTarget: Hành động:' Tôi mới trong ios, vẫn còn học hỏi, vì vậy xin lỗi. –

+0

Cảm ơn! Nếu làm như vậy, sự kiện TouchDown của tôi chỉ kích hoạt khi nhấp đúp. – Alex

3

Phương pháp này được thử nghiệm và nên làm những gì tôi nghĩ bạn đang cố gắng thực hiện. Bạn có thể thay đổi độ trễ trong bộ hẹn giờ để có được hiệu ứng bạn muốn. Tôi đã phải kết nối 3 hành động với nút để thực hiện công việc này - hành động thứ ba là một touchUp đặt lại hệ thống về điều kiện bắt đầu.

@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

Cảm ơn! Kéo chỉ làm việc OK lần đầu tiên. nhấp chuột, kéo lại không hoạt động. Tôi cần làm gì tiếp theo? Tôi không biết làm thế nào để kiểm soát bộ đếm thời gian. – Alex

+0

Bạn đã triển khai phương thức touchUpAction (và kết nối nó với nút) chưa? Nó làm việc tốt cho tôi, trên nhấp chuột lặp đi lặp lại và kéo. – rdelmar

+0

Cảm ơn Ngài! Mục tiêu của tôi touchDownAction. – Alex

Các vấn đề liên quan