Сочетание длинного нажатия и жеста перетаскивания - PullRequest
41 голосов
/ 14 февраля 2012

Я перемещаю свои взгляды на

UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(moveRight:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[bubbleView[rightCnt] addGestureRecognizer:panRecognizer];
[panRecognizer release];

Теперь я хочу сделать то же самое, перетаскивая при долгом нажатии.

Есть идеи?

Ответы [ 5 ]

83 голосов
/ 14 февраля 2012

UILongPressGestureRecognizer уже делает то, что вы хотите для вас. Посмотрите на свойство UIGestureRecognizerState. Из документации :

Жесты длинного нажатия являются непрерывными. Жест начинается (UIGestureRecognizerStateBegan), когда число допустимых пальцев (numberOfTouchesRequired) были нажаты за указанный период (минимальная длительность) и касания не выходят за пределы допустимый диапазон движения (allowableMovement). Жест распознаватель переходит в состояние изменения при каждом движении пальца, и это заканчивается (UIGestureRecognizerStateEnded), когда любой из пальцев подняты.

Таким образом, после вызова селектора UILongPressGestureRecognizer вы слушаете UIGestureRecognizerStateBegan, UIGestureRecognizerStateChanged, UIGestureRecognizerStateEnded. Продолжайте менять рамку вида во время UIGestureRecognizerStateChanged.

- (void)moveRight:(UILongPressGestureRecognizer *)gesture
{
    if(gesture.state == UIGestureRecognizerStateBegan)
    {
        //if needed do some initial setup or init of views here
    }
    else if(gesture.state == UIGestureRecognizerStateChanged)
    {
        //move your views here.
        [yourView setFrame:];
    }
    else if(gesture.state == UIGestureRecognizerStateEnded)
    {
        //else do cleanup
    }
}
36 голосов
/ 14 февраля 2012
@implementation MyViewController {
    CGPoint _priorPoint;
}

- (void)moveRight:(UILongPressGestureRecognizer *)sender {
    UIView *view = sender.view;
    CGPoint point = [sender locationInView:view.superview];
    if (sender.state == UIGestureRecognizerStateChanged) {
        CGPoint center = view.center;
        center.x += point.x - _priorPoint.x;
        center.y += point.y - _priorPoint.y;
        view.center = center;
    }
    _priorPoint = point;
}
3 голосов
/ 01 февраля 2017

В Swift это можно сделать с помощью кода ниже

class DragView: UIView { 
  // Starting center position
  var initialCenter: CGPoint?

  override func didMoveToWindow() {
    super.didMoveToWindow()
    // Add longPress gesture recognizer
    let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPressAction(gesture:)))
    addGestureRecognizer(longPress)
  }

  // Handle longPress action
  func longPressAction(gesture: UILongPressGestureRecognizer) {
    if gesture.state == .began {
        guard let view = gesture.view else {
            return
        }
        initialCenter = gesture.location(in: view.superview)
    }
    else if gesture.state == .changed {
        guard let originalCenter = initialCenter else {
            return
        }

        guard let view = gesture.view else {
            return
        }

        let point = gesture.location(in: view.superview)

        // Calculate new center position
        var newCenter = view.center;
        newCenter.x += point.x - originalCenter.x;
        newCenter.y += point.y - originalCenter.y;

        // Update view center
        view.center = newCenter
    }
    else if gesture.state == .ended {
       ...
    }
}
2 голосов
/ 15 ноября 2014

Вам не нужно объявлять _priorPoint;

В моем случае я хочу, чтобы представление двигалось только горизонтально, поэтому я изменяю только координату x.

Вот мое решение:

    if (longpressGestRec.state == UIGestureRecognizerStateChanged)
    {
        UIView *view = longpressGestRec.view;

        // Location of the touch within the view.
        CGPoint point = [longpressGestRec locationInView:view];

        // Calculate new X position based on the amount the gesture
        // has moved plus the size of the view we want to move.
        CGFloat newXLoc = (item.frame.origin.x + point.x) - (item.frame.size.width / 2);
        [item setFrame:CGRectMake(newXLoc,
                                  item.frame.origin.y,
                                  item.frame.size.width,
                                  item.frame.size.height)];
    }
1 голос
/ 23 марта 2018

Спасибо Хари Кунвар за код Swift, но функция longPressAction не определена правильно.

Вот улучшенная версия:

@objc func longPressAction(gesture: UILongPressGestureRecognizer)  {
    if gesture.state == UIGestureRecognizerState.began {
    }
    else if gesture.state == .changed {
        guard let view = gesture.view else {
            return
        }
        let location = gesture.location(in: self.view)
        view.center = CGPoint(x:view.center.x + (location.x - view.center.x),
                                          y:view.center.y + (location.y - view.center.y))
    }
    else if gesture.state == UIGestureRecognizerState.ended{
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...