2011-05-30 161 views
69

我想模仿长按按钮,我该怎么做?我认为需要一个计时器。 我看到UILongPressGestureRecognizer但我该如何利用这种类型?UIButton长按活动

回答

144

您可以通过创建并将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"); 
    } 
} 

现在,这将是基本方法的方法。您还可以设置印刷机的最短持续时间和可承受的误差。另外请注意,如果您在识别该手势后几次调用该方法,那么如果您想在其末尾执行某些操作,则必须检查其状态并处理它。

+0

超级!谢谢! btw:if(gesture.state == UIGestureRecognizerStateEnded)非常重要,否则你会在你的longPress中得到很多事件void – RecycleRobot 2013-05-24 12:25:22

+21

你可能想使用'if(gesture.state == UIGestureRecognizerStateBegan)',因为用户当他们还在按下时(状态开始),而不是当他们释放时(结束),他们期望发生什么事情。 – shengbinmeng 2014-10-23 13:40:16

8

试试这个:

在视图中添加按钮做负载这样

-(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 tag with recogniser tag 
//view frame for getting the info on which button the click event has been 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 dont need 
//to write frame comparing code if you are matching the tag number of button 
} 
+0

'recognizer.view.tag'给我错误标记的UIButton点击。任何解决方案 – 2013-03-20 11:32:40

15

手势的方法来接受的答案的替代,这可使用Interface Builder可以非常容易地在Xcode中完成。

刚从对象库拖动长按手势识别器拖放到你想要的长按操作按钮的顶部。

接下来,连接从长按手势识别器只是增加了一个行动,你的视图控制器,选择发件人是UILongPressGestureRecognizer类型。在这种IBAction这种使用,这是非常相似的代码的代码在接受的答案建议:

Objective-C的

if (sender.state == UIGestureRecognizerStateEnded) { 
    // Do your stuff here 
} 

或者在斯威夫特

if sender.state == .Ended { 
    // Do your stuff here 
} 

但我不得不承认,在尝试之后,我更喜欢@shengbinmeng提出的建议作为对已接受答案的评论,即使用:

Objective-C的

if (sender.state == UIGestureRecognizerStateBegan) { 
    // Do your stuff here 
} 

或者在斯威夫特

if sender.state == .Began { 
    // Do your stuff here 
} 

不同的是,与Ended,你看到长按的效果,当你抬起手指。使用Began时,即使在将手指从屏幕上抬起之前,只要系统抓住长按,就会看到长按的效果。

2

我认为你需要我的解决方案。

你应该有一个按

- (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; 
    } 
} 
0

我有我的应用程序的子类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:)]; 

该行为应该像所有的IBActions(没有IBAction)一样定义。

- (void)longPressAction:(id)sender { 
    // sender is the button 
} 
10

接受的答案

的斯威夫特版本我做了使用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") 
    } 
} 
0

无工作,因此我试着在IBAction或单击按钮写长按代码storyboardController,而不是写在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]; 

} 
0

对于斯威夫特4,“FUNC长按”需要改变,以让它工作:

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") 
    } 
}