我想模仿长按按钮,该怎么办?我认为需要一个计时器。我知道了,UILongPressGestureRecognizer
但是我该如何利用这种类型?
Answers:
您可以通过创建UILongPressGestureRecognizer
实例并将其附加到按钮开始。
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
[self.button addGestureRecognizer:longPress];
[longPress release];
然后实现处理手势的方法
- (void)longPress:(UILongPressGestureRecognizer*)gesture {
if ( gesture.state == UIGestureRecognizerStateEnded ) {
NSLog(@"Long Press");
}
}
现在,这将是基本方法。您还可以设置印刷机的最短持续时间以及允许的错误数量。还要注意的是,如果您在识别出手势之后便多次调用了该方法,那么如果您想在其结束时执行某些操作,则必须检查其状态并进行处理。
if(gesture.state == UIGestureRecognizerStateBegan)
,因为用户希望在他们仍然按下(状态为Began)时发生某些事情,而不是在释放时(Ended)发生某件事。
作为公认答案的替代方法,这可以使用Interface Builder在Xcode中轻松完成。
只需将“长按手势识别器”从“对象库”中拖放到想要长按动作的按钮顶部即可。
接下来,将刚添加的“长按手势识别器”中的“动作”连接到视图控制器,选择类型为“发件人”的发件人UILongPressGestureRecognizer
。在IBAction
使用此代码的代码中,这与已接受的答案中建议的代码非常相似:
在Objective-C中:
if ( sender.state == UIGestureRecognizerStateEnded ) {
// Do your stuff here
}
或在Swift中:
if sender.state == .Ended {
// Do your stuff here
}
但是我必须承认,尝试之后,我更喜欢@shengbinmeng提出的建议作为对已接受答案的注释,该建议使用:
在Objective-C中:
if ( sender.state == UIGestureRecognizerStateBegan ) {
// Do your stuff here
}
或在Swift中:
if sender.state == .Began {
// Do your stuff here
}
区别在于,使用Ended
,您可以在抬起手指时看到长按的效果。使用Began
,您会在系统抓住长按后立即看到长按的效果,甚至在手指离开屏幕之前也是如此。
我对using进行了其他修改,UIGestureRecognizerState.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")
}
}
试试这个:
在添加按钮,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];
}
现在像这样调用手势方法
-(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
}
recognizer.view.tag
给我的UIButton的错误标签单击。有什么办法吗?
我认为您需要我的解决方案。
您应该具有此代码以供单按
- (IBAction)buttonDidPress:(id)sender {
NSLog("buttonDidPress");
}
首先,向按钮添加长按手势
- (void)viewWillAppear:(BOOL)animated
{
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(buttonDidLongPress:)];
[self.button addGestureRecognizer:longPress];
}
然后,如果识别出长按手势,则反复调用单按事件。
- (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;
}
}
UIGestureRecognizer
在viewWillAppear
生命周期事件中添加,因为每当视图出现时,都会添加另一个手势识别器。这应该在初始化期间调用的私有方法中完成。
对于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")
}
}
单行答案,无手势:
[btn addTarget:self action:@selector(handleTouch:) forControlEvents:UIControlEventTouchDown | UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
详细信息:
这将在以下三个事件上触发您的目标:1-一旦手指触摸按钮:UIControlEventTouchDown
。这将捕获长按开始。2&3-当用户抬起手指时:UIControlEventTouchUpOutside
&UIControlEventTouchUpInside
。这捕获了用户按下的结尾。
注意:如果您不关心手势识别器提供的额外信息(例如,触摸的位置等),则此方法很好用
如果需要,您可以添加更多中间事件,请参见https://developer.apple.com/documentation/uikit/uicontrolevents?language=objc。
在Storyboard中: 将您的按钮连接到3个事件,而不仅仅是Storyboard选择的默认事件(Touch Up Inside)。
我的应用程序有一个子类UIButton,因此我退出了实现。您可以将其添加到子类中,也可以像UIButton类别一样轻松地对其进行重新编码。
我的目标是将长按添加到我的按钮上,而不会使所有代码混乱我的视图控制器。我已经决定在手势识别器状态开始时应调用该动作。
发出警告,我从未想过要解决。说这是可能的泄漏,以为我已经测试了代码并且没有泄漏。
@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];
}
}
要分配操作,请将此行添加到viewDidLoad方法。
[_myLongButton addLongPressTarget:0.75 target:self selector:@selector(longPressAction:)];
应该像所有IBAction(没有IBAction)一样定义该动作。
- (void)longPressAction:(id)sender {
// sender is the button
}
没有任何效果,因此我尝试在其中写入longpress代码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];
}