Я хочу подражать долгое нажатие кнопки, как я могу это сделать? Я думаю, нужен таймер.
Я вижу UILongPressGestureRecognizer, но как я могу использовать этот тип?
UIButton Long Press Event
Ответ 1
Вы можете начать с создания и присоединения экземпляра 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");
    }
}
Теперь это будет основной подход. Вы также можете установить минимальную продолжительность печати и насколько допустимая погрешность. А также обратите внимание, что метод вызывается несколько раз, если вы после распознавания жестов, поэтому, если вы хотите что-то сделать в конце, вам нужно будет проверить его состояние и обработать его.
Ответ 2
В качестве альтернативы принятому ответу это можно сделать очень легко в Xcode с помощью Interface Builder.
Просто перетащите указатель жестов с длинным нажатием в библиотеке объектов и опустите его поверх кнопки, где вы хотите долгое нажатие.
Затем подключите действие с помощью распознавателя жестов длинного нажатия, только добавленное к вашему контроллеру просмотра, выбрав отправителя типа 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 вы увидите эффект продолжительного нажатия, как только длинное нажатие улавливается системой, даже до того, как вы отпустите палец с экрана.
Ответ 3
Быстрая версия принятого ответа
Я сделал дополнительную модификацию использования UIGestureRecognizerState.Began, а не .Ended, поскольку это, вероятно, то, что, естественно, ожидало бы большинство пользователей. Попробуйте их обоих и убедитесь сами.
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)
    }
    func longPress(guesture: UILongPressGestureRecognizer) {
        if guesture.state == UIGestureRecognizerState.Began {
            print("Long Press")
        }
    }
    @IBAction func normalButtonTap(sender: UIButton) {
        print("Button tapped")
    }
}
Ответ 4
Попробуйте следующее:
Добавление кнопки в поле зрения загрузилось следующим образом
-(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 click code here
 }
   //and you can also compare the frame of your button with recogniser view
 CGRect btnRect = CGRectMake(50.0, 50.0, 60.0, 60.0);
 if(recogniser.view.frame == btnRect)
 {
   //put your button 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 
}
Ответ 5
Думаю, вам нужно мое решение.
у вас должен быть этот код для однократного нажатия
- (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;
    }
}
Ответ 6
Использование доски для распознавания жестов намного проще. Проверьте это видео из Стэнфорда для распознавания жестов. https://www.youtube.com/watch?v=85IUfbgp0v8
Ответ 7
У меня есть подкласса 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
}
Ответ 8
Не работал, поэтому я попробовал записать длинный код в 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];
}
