Объединение UILongPressGestureRecognizer с UIPanGestureRecognizer
Мне нравится комбинировать UILongPressGestureRecognizer с UIPanGestureRecognizer.
UIPanGestureRecognizer должен начинаться с длительного нажатия. Есть ли простой способ сделать это? или мне действительно нужно написать свой собственный распознаватель жестов?
На главном экране ничего не было. Вы нажимаете на значок, и через некоторое время значки начинают дрожать. Впоследствии, не отпуская мой палец с экрана, я могу начать перетаскивать значок под пальцем.
Ответы
Ответ 1
Я нашел решение:
Этот метод UIGestureRecognizerDelegate делает именно то, что я искал:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
Ответ 2
на самом деле вам не нужно комбинировать распознаватели жестов - вы можете делать это исключительно с помощью UILongPressGestureRecognizer... Вы вводите StateBegan, когда ваши прикосновения остались в пределах допустимого перехода для "minimumPressDuration". Вы остаетесь в своем непрерывном longPressGesture, пока вы не поднимаете ни одного пальца, - поэтому вы можете начать перемещать пальцы и отслеживать движение через StateChanged.
Жесты непрерывной печати непрерывны. Жест начинается (UIGestureRecognizerStateBegan), когда число допустимых пальцев (numberOfTouchesRequired) было нажато в течение заданного периода (minimumPressDuration), и штрихи не выходят за допустимый диапазон движения (допустимое перемещение). Устройство распознавания жестов переходит в состояние изменения всякий раз, когда движется палец, и заканчивается (UIGestureRecognizerStateEnded), когда любой из пальцев поднимается.
Ответ 3
У меня было немного времени для этой проблемы. Принятого ответа было недостаточно. Независимо от того, что я вложил в этот метод, обработчики панорамирования или longpress будут вызваны. Решение, которое я нашел, было следующим:
- Убедитесь, что делегаты распознавателей жестов назначены одному классу (в моем случае self) и убедитесь, что класс делегата является
UIGestureRecognizerDelegate
.
-
Добавьте в свой класс следующий метод делегата (в соответствии с приведенным выше ответом):
- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
-
Добавьте в свой класс следующий метод делегата:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && ! shouldAllowPan) {
return NO;
}
return YES;
}
-
Затем добавьте свойство или ivar, который будет отслеживать, нужно ли запустить панорамирование (см. метод выше). В моем случае BOOL shouldAllowPan
.
-
Установите BOOL на NO
в init
или viewDidLoad
. Внутри обработчика longPress установите BOOL на YES
. Я делаю это так:
- (void) longPressHandler: (UILongPressGestureRecognizer *) gesture {
if(UIGestureRecognizerStateBegan == gesture.state) {
shouldAllowPan = NO;
}
if(UIGestureRecognizerStateChanged == gesture.state) {
shouldAllowPan = YES;
}
}
-
Внутри panHandler я проверяю BOOL:
- (void)panHandler:(UIPanGestureRecognizer *)sender{
if(shouldAllowPan) {
// do your stuff
}
-
И, наконец, reset BOOL внутри panHandler:
else if(sender.state == UIGestureRecognizerStateEnded || sender.state == UIGestureRecognizerStateFailed || sender.state == UIGestureRecognizerStateCancelled) {
shouldAllowPan = NO;
}
-
И тогда пойди, возьмите пиво, чтобы поздравить себя.;)
Ответ 4
Подход Энди Б. в Свифт,
-
Добавьте делегата UIGestureRecognizerDelegate в класс
class ViewController: UIViewController, UIGestureRecognizerDelegate
-
Добавить переменную-член
var shouldAllowPan: Bool = false
-
Добавьте жесты и добавьте делегат ggter von в VC. Это необходимо, чтобы отключить функции shouldRecognizeSimultaneousWithGestureRecognizer и gestureRecognizerShouldBegin
// long press
let longPressRec = UILongPressGestureRecognizer(target: self, action: "longPress:")
yourView.addGestureRecognizer(longPressRec)
// drag
let panRec = UIPanGestureRecognizer(target: self, action: "draggedView:")
panRec.delegate = self
yourView.addGestureRecognizer(panRec)
-
Разрешить одновременные жесты
func gestureRecognizer(UIGestureRecognizer,
shouldRecognizeSimultaneouslyWithGestureRecognizer:UIGestureRecognizer) -> Bool {
// println("shouldRecognizeSimultaneouslyWithGestureRecognizer");
return true
}
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
// We only allow the (drag) gesture to continue if it is within a long press
if((gestureRecognizer is UIPanGestureRecognizer) && (shouldAllowPan == false)) {
return false;
}
return true;
}
-
Внутри длинного обработчика:
func longPress(sender: UILongPressGestureRecognizer) {
if(sender.state == .Began) {
// handle the long press
}
else if(sender.state == .Changed){
shouldAllowPan = true
}
else if (sender.state == .Ended) {
shouldAllowPan = false
}
}
Ответ 5
Прочтите раздел "Примечания к подклассам" в Справочнике классов Apple UIGestureRecognizer по адресу:
https://developer.apple.com/library/prerelease/tvos/documentation/UIKit/Reference/UIGestureRecognizer_Class/