如何在UIButton中实现两个不重叠的IBActions?
我拖动2 IBActions从UIButton
,一个touchDown事件,第二个拖动里面。如何在UIButton中实现两个不重叠的IBActions?
- (IBAction)clickButton:(UIButton *)sender {
NSLog(@"Click Button");
}
- (IBAction)dragInsideButton:(UIButton *)sender {
NSLog(@"Drag Button");
}
但是当我拖入里面时,touchDown动作也被触发。
如何在dragInside时禁用touchDown事件。
谢谢!
我已经解决了这样的问题,使用拖放事件
事件添加到您的按钮中的.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
}
}
我不知道它会工作,但你可以尝试
- (IBAction)dragInsideButton:(UIButton *)sender {
[sender removeTarget:self forSelector:@selector(clickButton:) forControlEvent:UIControlEventTouchDown];
}
谢谢!这是不行的,因为touchDown在拖动之前触发。 – Alex 2013-03-23 15:54:29
我从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行动的评论中注意到了。我没有测试过,但它应该可以工作。
试试这个方法:
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在按钮动作首先被调用。
这种方法已经过测试,应该做我认为你正在尝试做的事情。您可以更改计时器中的延迟以获得所需的效果。我必须将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;
}
只是一个猜测,做一个BOOL和两个方法检查,并通过翻转动作:' - (空) removeTarget:action:' – 2013-03-23 15:44:24
您是否也希望发生相反的情况 - 也就是说,如果touchDown被触发,您是否需要dragInside不会在用户开始拖动时发生?做这项工作的唯一方法是在开始时稍微延迟一段时间,看看是否有阻力开始。如果这是不可接受的,那么你将不得不采用不同的设计。 – rdelmar 2013-03-23 17:09:31