Я хочу емулювати довге натискання кнопки, як я можу це зробити? Думаю, потрібен таймер. Я розумію, UILongPressGestureRecognizer
але як я можу використовувати цей тип?
Відповіді:
Ви можете почати зі створення та приєднання 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)
, тому що користувач очікує, що щось трапиться тоді, коли вони все ще натискають (стан розпочато), а не коли вони звільняють (закінчено).
Як альтернативу прийнятій відповіді, це можна зробити дуже легко в Xcode за допомогою Interface Builder.
Просто перетягніть розпізнавач жестів довгим натисканням з бібліотеки об’єктів і опустіть його зверху на кнопку, де потрібно виконати тривале натискання.
Далі підключіть дію із щойно доданого розпізнавача жестів довгим натисканням до вашого контролера перегляду, вибравши відправника, якого потрібно ввести UILongPressGestureRecognizer
. У коді, що IBAction
використовує це, дуже схоже на код, запропонований у прийнятій відповіді:
У цілі-C :
if ( sender.state == UIGestureRecognizerStateEnded ) {
// Do your stuff here
}
Або в Свіфт :
if sender.state == .Ended {
// Do your stuff here
}
Але я повинен визнати, що спробувавши, я віддаю перевагу пропозиції @shengbinmeng як коментар до прийнятої відповіді, яка мала використовуватись:
У цілі-C :
if ( sender.state == UIGestureRecognizerStateBegan ) {
// Do your stuff here
}
Або в Свіфт :
if sender.state == .Began {
// Do your stuff here
}
Різниця полягає в тому, що з Ended
, ви бачите ефект тривалого натискання, коли ви піднімаєте палець. З цим Began
ви бачите ефект тривалого натискання, як тільки система натискає на довге натискання, ще до того, як ви відведете палець від екрана.
Я зробив додаткову модифікацію використання, 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
дає мені неправильний тег натиснутого кнопки UIB. Будь-яке рішення?
Я думаю, вам потрібне моє рішення.
ви повинні мати цей код для одного натискання
- (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 подій, а не лише до тієї, що вибрана за замовчуванням (Story 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:)];
Дія повинна бути визначена як усі IBActions (без 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];
}