简体   繁体   English

是否可以区分长按和按下按钮?

[英]Is it possible to differentiate between a long press and a tap on a button?

Can we call different actions / delegates in response to the two different events of 我们可以调用不同的行动/代表来回应两个不同的事件

  1. A tap on a UIButton 点击UIButton
  2. A tap-and-hold on a UIButton 在UIButton上点击并按住

?

Yes, it's reasonably easy to implement this using a UILongPressGestureRecognizer (on iPhone OS 3.2+). 是的,使用UILongPressGestureRecognizer(在iPhone OS 3.2+上)实现此功能相当容易。 A long press will be handled by the gesture recognizer, and a short tap will pass through to the button's normal action. 长按将由手势识别器处理,短按将通过按钮的正常操作。

For example, I subclassed UIButton and added the following method for specifying a long touch action to go along with a tap ( longPressGestureRecognizer is an instance variable): 例如,我将UIButton子类化,并添加了以下方法来指定长按触摸操作( longPressGestureRecognizer是一个实例变量):

- (void)setLongTouchAction:(SEL)newValue
{
    if (newValue == NULL)
    {
        [self removeGestureRecognizer:longPressGestureRecognizer];
        [longPressGestureRecognizer release];
        longPressGestureRecognizer = nil;
    }
    else
    {
        [longPressGestureRecognizer release];
        longPressGestureRecognizer = nil;

        longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:[[self allTargets] anyObject] action:newValue];
        [self addGestureRecognizer:longPressGestureRecognizer];
    }
}

I then could do the following to set both short tap and long press actions that will be handled by the same target: 然后,我可以执行以下操作来设置将由同一目标处理的短击和长按操作:

[undoButton addTarget:self action:@selector(performUndo:) forControlEvents:UIControlEventTouchUpInside];
[undoButton setLongTouchAction:@selector(showUndoOptions:)];

As you can see, this is useful for the undo buttons you see in title bars of many iPad applications. 如您所见,这对于您在许多iPad应用程序的标题栏中看到的撤消按钮很有用。

Brad Larson's answer looks pretty good but here's another one that might give you a bit more flexibility/control of what you want or might want to do. 布拉德拉森的答案看起来很不错,但这是另一个可能会让你更灵活/控制你想要或可能想做的事情。

You subclass UIButton, you override the touchesBegan and touchesEnded methods so that when the user starts a touch you call 你是UIButton的子类,你重写了touchesBegan和touchesEnded方法,这样当用户开始触摸时你会调用

[self performSelector:@selector(detecetedLongTap) withObject:nil afterDelay:1.0];

and in the touchesEnded you call: 在触摸中,你打电话给:

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(detecetedLongTap) object:nil];

to cancel the event if the finger was lifted too soon. 如果手指过早抬起则取消该事件。

You can get full code for this in this blog post: 您可以在此博客文章中获取完整的代码:

http://www.isignmeout.com/adding-long-tap-functionality-uibutton/ http://www.isignmeout.com/adding-long-tap-functionality-uibutton/

The best solution I can think of, is to create another class, and subclass UIButton. 我能想到的最好的解决方案是创建另一个类,并创建UIButton的子类。 Then on Interface Builder (if that's what you're using), you can set the button's class to the custom class you just created. 然后在Interface Builder上(如果这就是您正在使用的),您可以将按钮的类设置为您刚刚创建的自定义类。

So in this new class, you have to override a method called 所以在这个新类中,你必须覆盖一个名为的方法

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

This is basically telling you that someone pressed down on your button. 这基本上告诉你有人按下你的按钮。 The touches is an NSSet and it holds all the information for all the fingers that are pressing down on the screen. 触摸是一个NSSet,它保存所有按下屏幕的手指的所有信息。 If you only are interested in the one that's pressing on the button itself, you'll probably have something like: 如果你只对那个按下按钮的人感兴趣,你可能会有类似的东西:

NSSet *myTouches = [event touchesForView:self.view];

So now that you have the touches that correspond to your button, you have to find out how many times the user tapped on that button. 现在您已经拥有了与按钮相对应的触摸,您必须找出用户点击该按钮的次数。 You do that with something like: 你这样做是这样的:

NSUInteger numTaps = [[myTouches anyObject] tapCount];

If this number is 2, that means the user just double tapped your button. 如果此数字为2,则表示用户只需双击您的按钮。 Now comes the next part. 现在是下一部分。 How do you know if the user is holding that button? 你怎么知道用户是否拿着那个按钮? Well when the user lets go of the screen, another method gets called. 当用户放开屏幕时,会调用另一个方法。 You'll need to override that one as well: 您还需要覆盖那个:

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

This is where you know if the person has stopped touching the screen or if his finger is still on it. 您可以在此处知道此人是否已停止触摸屏幕或手指是否仍在屏幕上。 If his finger is still on it, then this event hasn't been called yet. 如果他的手指仍在上面,那么此事件尚未被调用。

Now enough with the background 现在足够的背景

Here's my suggestion to you. 这是我给你的建议。 I suggest you override the touchesBegan: method and check if the number of taps in the button is 2. If so, then start a timer that does what you need it to do, for as long as you need it to be done, and then on the touchesEnded: method, you'll go ahead and stop that timer, and this way you will have done whatever it is that you needed to do, for as long as you needed to do it OR as long as the user has held on to the button. 我建议你覆盖touchesBegan:方法并检查按钮中的水龙头数是否为2.如果是,那么启动一个计时器,做你需要它做的事,只要你需要它完成,然后在touchesEnded:方法中,你将继续并停止该计时器,这样你就可以完成你需要做的任何事情,只要你需要这样做或者只要用户坚持下去到按钮。

I hope this helps, obviously I didn't write the whole code for you, you'll have to experiment and research that stuff, but if you have any questions, I'll be happy to lend a helping hand :) 我希望这有帮助,显然我没有为你编写整个代码,你必须尝试和研究那些东西,但如果你有任何问题,我会很乐意伸出援助之手:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM