ios UIButton 长按事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6179347/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UIButton Long Press Event
提问by Andrea
I want to emulate a long a press button, how can I do this? I think a timer is needed.
I see UILongPressGestureRecognizer
but how can I utilize this type?
我想模拟一个长按按钮,我该怎么做?我认为需要一个计时器。我明白了,UILongPressGestureRecognizer
但我该如何利用这种类型?
回答by Deepak Danduprolu
You can start off by creating and attaching the UILongPressGestureRecognizer
instance to the button.
您可以首先创建UILongPressGestureRecognizer
实例并将其附加到按钮。
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[self.button addGestureRecognizer:longPress];
[longPress release];
And then implement the method that handles the gesture
然后实现处理手势的方法
- (void)longPress:(UILongPressGestureRecognizer*)gesture {
if ( gesture.state == UIGestureRecognizerStateEnded ) {
NSLog(@"Long Press");
}
}
Now this would be the basic approach. You can also set the minimum duration of the press and how much error is tolerable. And also note that the method is called few times if you after recognizing the gesture so if you want to do something at the end of it, you will have to check its state and handle it.
现在这将是基本方法。您还可以设置按下的最短持续时间以及可以容忍的错误量。还要注意,如果您在识别手势后调用该方法几次,因此如果您想在它结束时执行某些操作,则必须检查其状态并处理它。
回答by alondono
As an alternative to the accepted answer, this can be done very easily in Xcode using Interface Builder.
作为已接受答案的替代方案,这可以在 Xcode 中使用 Interface Builder 轻松完成。
Just drag a Long Press Gesture Recognizerfrom the Object Libraryand drop it on top of the button where you want the long press action.
只需从对象库中拖动一个Long Press Gesture Recognizer并将其放在您想要长按操作的按钮顶部。
Next, connect an Action from the Long Press Gesture Recognizerjust added, to your view controller, selecting the sender to be of type UILongPressGestureRecognizer
. In the code of that IBAction
use this, which is very similar to the code suggested in the accepted answer:
接下来,将刚刚添加的Long Press Gesture Recognizer 中的 Action 连接到您的视图控制器,选择类型为 的发送者UILongPressGestureRecognizer
。在IBAction
使用它的代码中,它与接受的答案中建议的代码非常相似:
In Objective-C:
在Objective-C 中:
if ( sender.state == UIGestureRecognizerStateEnded ) {
// Do your stuff here
}
Or in Swift:
或者在Swift 中:
if sender.state == .Ended {
// Do your stuff here
}
But I have to admit that after trying it, I prefer the suggestion made by @shengbinmeng as a comment to the accepted answer, which was to use:
但我不得不承认,在尝试之后,我更喜欢@shengbinmeng 提出的建议作为对已接受答案的评论,即使用:
In Objective-C:
在Objective-C 中:
if ( sender.state == UIGestureRecognizerStateBegan ) {
// Do your stuff here
}
Or in Swift:
或者在Swift 中:
if sender.state == .Began {
// Do your stuff here
}
The difference is that with Ended
, you see the effect of the long press when you lift your finger. With Began
, you see the effect of the long press as soon as the long press is caught by the system, even before you lift the finger off the screen.
不同之处在于Ended
,当您抬起手指时,您会看到长按的效果。使用Began
,只要系统捕捉到长按,您就可以看到长按的效果,甚至在您将手指从屏幕上移开之前。
回答by Suragch
Swift version of the accepted answer
已接受答案的 Swift 版本
I made the additional modification of using UIGestureRecognizerState.Began
rather than .Ended
since that is probably what most users would naturally expect. Try them both and see for yourself, though.
我对 usingUIGestureRecognizerState.Began
而不是进行了额外的修改,.Ended
因为这可能是大多数用户自然期望的。不过,请尝试两者并亲眼看看。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// add gesture recognizer
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPress(_:)))
self.button.addGestureRecognizer(longPress)
}
func longPress(gesture: UILongPressGestureRecognizer) {
if gesture.state == UIGestureRecognizerState.began {
print("Long Press")
}
}
@IBAction func normalButtonTap(sender: UIButton) {
print("Button tapped")
}
}
回答by TheTiger
Try this:
尝试这个:
Adding button in viewDidLoad:
like below
添加按钮viewDidLoad:
如下
-(void)viewDidLoad {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setTag:1]; //you can set any integer value as tag number
btn.title = @"Press Me";
[btn setFrame:CGRectMake(50.0, 50.0, 60.0, 60.0)];
// now create a long press gesture
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressTap:)];
[btn addGestureRecognizer:longPress];
}
Now call the gesture method like this
现在像这样调用手势方法
-(void)longPressTap:(id)sender {
UIGestureRecognizer *recognizer = (UIGestureRecognizer*) sender
// Recogniser have all property of button on which you have clicked
// Now you can compare button's tag with recogniser's view.tag
// View frame for getting the info on which button the click event happened
// Then compare tag like this
if(recognizer.view.tag == 1) {
// Put your button's click code here
}
// And you can also compare the frame of your button with recogniser's view
CGRect btnRect = CGRectMake(50.0, 50.0, 60.0, 60.0);
if(recogniser.view.frame == btnRect) {
//put your button's click code here
}
// Remember frame comparing is alternative method you don't need to write frame comparing code if you are matching the tag number of button
}
回答by Jerry Juang
I think you need my solution.
我想你需要我的解决方案。
you should have this code for single press
你应该有这个代码用于单次按下
- (IBAction)buttonDidPress:(id)sender {
NSLog("buttonDidPress");
}
first, add long press gesture to button
首先,为按钮添加长按手势
- (void)viewWillAppear:(BOOL)animated
{
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(buttonDidLongPress:)];
[self.button addGestureRecognizer:longPress];
}
then call single press event repeatedly if long press gesture is recognized.
如果识别出长按手势,则重复调用单按事件。
- (void)buttonDidLongPress:(UILongPressGestureRecognizer*)gesture
{
switch (gesture.state) {
case UIGestureRecognizerStateBegan:
{
self.timer = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(buttonDidPress:) userInfo:nil repeats:YES];
NSRunLoop * theRunLoop = [NSRunLoop currentRunLoop];
[theRunLoop addTimer:self.timer forMode:NSDefaultRunLoopMode];
}
break;
case UIGestureRecognizerStateEnded:
{
[self.timer invalidate];
self.timer = nil;
}
break;
default:
break;
}
}
回答by Bevan
For Swift 4, the "func longPress" needs to be changed to make it work:
对于 Swift 4,需要更改“func longPress”以使其工作:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// add guesture recognizer
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPress(_:)))
self.button.addGestureRecognizer(longPress)
}
@objc func longPress(_ guesture: UILongPressGestureRecognizer) {
if guesture.state == UIGestureRecognizerState.began {
print("Long Press")
}
}
@IBAction func normalButtonTap(sender: UIButton) {
print("Button tapped")
}
}
回答by CSawy
One-line answer, with no gestures:
单行回答,无需手势:
[btn addTarget:self action:@selector(handleTouch:) forControlEvents:UIControlEventTouchDown | UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
[btn addTarget:self action:@selector(handleTouch:) forControlEvents:UIControlEventTouchDown | UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
Details:This triggers your target on three events:
1- Immediately once finger touches down the button: UIControlEventTouchDown
. This captures long presses start.
2 & 3- When user lifts finger up: UIControlEventTouchUpOutside
& UIControlEventTouchUpInside
. This captures end of the user press.
详细信息:这会在三个事件上触发您的目标: 1- 一旦手指按下按钮,立即:UIControlEventTouchDown
。这会捕获长按启动。2 & 3- 当用户抬起手指时:UIControlEventTouchUpOutside
& UIControlEventTouchUpInside
。这将捕获用户按下的结束。
Note: this works well if you don't care about the extra info provided by the gesture recognizer (e.g. location of touch, etc.)
注意:如果您不关心手势识别器提供的额外信息(例如触摸位置等),这很有效。
You can add more intermediate events if needed see them all here https://developer.apple.com/documentation/uikit/uicontrolevents?language=objc.
如果需要看到他们都在这里,您可以添加更多的中间事件https://developer.apple.com/documentation/uikit/uicontrolevents?language=objc。
In Storyboard:Connect your button to the 3 events, not just the default one that Storyboard selects (Touch Up Inside).
在 Storyboard 中:将您的按钮连接到 3 个事件,而不仅仅是 Storyboard 选择的默认事件(Touch Up Inside)。
回答by karan
None worked hence I tried writing longpress code in IBAction
or button click from storyboard
in Controller
instead of writing in viewDidLoad
没有奏效,因此我尝试编写长按代码IBAction
或从storyboard
输入按钮单击Controller
而不是输入viewDidLoad
- (IBAction)btnClick:(id)sender {
tag = (int)((UIButton *)sender).tag;
// Long press here instead of in viewDidLoad
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
longPress.cancelsTouchesInView = NO;
[sender addGestureRecognizer:longPress];
}
回答by Dan Loughney
I have a subclassed UIButton for my app, so I've pulled out my implementation. You can add this to your subclass or this could just as easily be recoded as a UIButton category.
我有一个子类的UIButton我的应用程序,所以我拿出我的实现。您可以将其添加到您的子类中,或者这可以像 UIButton 类别一样轻松地重新编码。
My goal was to add the long press to my button without cluttering my view controllers with all of the code. I've decided that the action should be called when the gesture recognizer state begins.
我的目标是将长按添加到我的按钮上,而不会用所有代码使我的视图控制器混乱。我决定在手势识别器状态开始时调用该动作。
There is a warning that comes out that I've never bothered to solve. Says it is a possible leak, thought I've tested the code and it doesn't leak.
有一个警告出现,我从来没有费心去解决。说这是一个可能的泄漏,以为我已经测试了代码并且它没有泄漏。
@interface MYLongButton ()
@property (nonatomic, strong) UILongPressGestureRecognizer *gestureRecognizer;
@property (nonatomic, strong) id gestureRecognizerTarget;
@property (nonatomic, assign) SEL gestureRecognizerSelector;
@end
@implementation MYLongButton
- (void)addLongPressTarget:(CGFloat)interval target:(id)target action:(SEL)selector
{
_gestureRecognizerTarget = target;
_gestureRecognizerSelector = selector;
_gestureRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleLongPressGestureRecognizer:)];
_gestureRecognizer.minimumPressDuration = interval;
[self addGestureRecognizer:_gestureRecognizer];
}
- (void)handleLongPressGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
NSAssert([_gestureRecognizerTarget respondsToSelector:_gestureRecognizerSelector], @"target does not respond to selector");
self.highlighted = NO;
// warning on possible leak -- can anybody fix it?
[_gestureRecognizerTarget performSelector:_gestureRecognizerSelector withObject:self];
}
}
To assign the action add this line to your viewDidLoad method.
要分配操作,请将此行添加到您的 viewDidLoad 方法。
[_myLongButton addLongPressTarget:0.75 target:self selector:@selector(longPressAction:)];
The action should be defined like all IBActions (without the IBAction).
动作应该像所有 IBAction 一样定义(没有 IBAction)。
- (void)longPressAction:(id)sender {
// sender is the button
}