Ограничение UIPanGestureRecognizer на координаты

Я добавил в свой основной UIView подвид (названный panel) и добавил к нему жестRecognizer, потому что я хочу, чтобы его можно было перетаскивать только для оси Y и только для определенных пределов (например, 160, 300, более 300). это не может идти).

Я реализовал обработку жестов таким образом

- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
    CGPoint translation = [recognizer translationInView:self.view]; 
    recognizer.view.center = CGPointMake(self.view.frame.size.width/2, recognizer.view.center.y + translation.y);
    [recognizer setTranslation:CGPointMake(0, 0) inView:self.view.superview];

    //now limit the drag to some coordinates
   if (y == 300 || y == 190){
       no more drag
    }
}

но теперь я не знаю, как ограничить перетаскивание этими координатами.

Это не огромное представление, это просто маленькое представление, содержащее панель инструментов и кнопку.

Как я могу ограничить перетаскивание координатой? (x = 160 (средний экран), y = 404) ‹- пример

Какой там должен быть центр?

Я много гуглил, но не нашел конкретного ответа.

заранее спасибо


person Phillip    schedule 11.07.2012    source источник


Ответы (3)


Во-первых, вам нужно применить ограничение, прежде чем изменить центр представления. Ваш код изменяет центр представления, прежде чем проверять, не выходит ли новый центр за пределы.

Во-вторых, вам нужно использовать правильные операторы C для проверки координаты Y. Оператор = является присваиванием. Оператор == проверяет равенство, но вы также не хотите его использовать.

В-третьих, вы, вероятно, не захотите сбрасывать перевод распознавателя, если новый центр находится за пределами границ. Сброс перевода, когда перетаскивание выходит за границы, отключит палец пользователя от вида, который он перетаскивает.

Вы, вероятно, хотите что-то вроде этого:

- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
    CGPoint translation = [recognizer translationInView:self.view];

    // Figure out where the user is trying to drag the view.
    CGPoint newCenter = CGPointMake(self.view.bounds.size.width / 2,
        recognizer.view.center.y + translation.y);

    // See if the new position is in bounds.
    if (newCenter.y >= 160 && newCenter.y <= 300) {
        recognizer.view.center = newCenter;
        [recognizer setTranslation:CGPointZero inView:self.view];
    }
}
person rob mayoff    schedule 11.07.2012
comment
Да, с оператором дело было по моей вине (может, из-за спешки!). Большое спасибо, все работает отлично! - person Phillip; 12.07.2012
comment
Роб: Спасибо. Это сработало. Хотя я все еще пытаюсь понять, зачем вам recognizer setTranslation:CGPointZero в последней строке. Я попытался прокомментировать это, и объект, который должен двигаться, выходит из области касания пальца и плавает на экране. Некоторая разработка была бы оценена. - person rohan-patel; 03.06.2014
comment
По умолчанию перевод распознавателя показывает, насколько далеко продвинулось касание с момента его начала. Но мы уже скорректировали положение представления для всего движения вверх до момента последнего срабатывания распознавателя. Сброс перевода распознавателя на ноль после каждого обновления означает, что при следующем обновлении перевод будет включать только движение касания с момента предыдущего обновления. - person rob mayoff; 03.06.2014

Вероятно, есть непреднамеренное последствие ответа Роба. Если вы перетащите достаточно быстро, newCenter выйдет за пределы, но это может произойти до последнего обновления. Это приведет к тому, что вид не будет панорамирован до конца. Вместо того, чтобы не обновлять, если newCenter выходит за пределы, вы всегда должны обновлять центр, но ограничивать границы следующим образом:

- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
    CGPoint translation = [recognizer translationInView:self.view];

    // Figure out where the user is trying to drag the view.
    CGPoint newCenter = CGPointMake(self.view.bounds.size.width / 2,
    recognizer.view.center.y + translation.y);

    // limit the bounds but always update the center
    newCenter.y = MAX(160, newCenter.y);
    newCenter.y = MIN(300, newCenter.y);

    recognizer.view.center = newCenter;
    [recognizer setTranslation:CGPointZero inView:self.view];
}
person Oren    schedule 08.01.2015
comment
преклоняюсь перед этим ответом, я считаю его намного лучше, чем тот, который был принят в качестве ответа! - person jane; 15.04.2016

Выше оба ответа верны для координаты Y. Это для тех, кто ищет координаты X и Y. Просто сделал небольшие изменения.

- (void)panWasRecognized:(UIPanGestureRecognizer *)panner {
    UIView *piece = [panner view];
    CGPoint translation = [panner translationInView:[piece superview]];

    CGPoint newCenter = CGPointMake(panner.view.center.x + translation.x,
                                    panner.view.center.y + translation.y);
    if (newCenter.y >= 0 && newCenter.y <= 300 && newCenter.x >= 0 && newCenter.x <=300) 
    {
        panner.view.center = newCenter;
        [panner setTranslation:CGPointZero inView:[piece superview]];
    }
}
person dmaulikr    schedule 20.07.2017