Сочетание длинного нажатия и жеста перетаскивания
Я двигаю свои взгляды
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 ответов
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
}
}
@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;
}
В 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 {
...
}
}
Вам не нужно объявлять _priorPoint;
В моем случае я хочу, чтобы представление двигалось только горизонтально, поэтому я изменяю только координату х.
Вот мое решение:
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)];
}
Спасибо Хари Кунвар за код 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{
}
}