Подтвердить что ты не робот

UIPinchGestureRecognizer позиционирует защемленный вид между двумя пальцами

Я успешно реализовал масштабирование масштабирования вида. Тем не менее, мнение не позиционирует себя так, как я хотел. Для stackoverflowers с iPad я хотел бы, чтобы мой взгляд был центрирован, как на iPad Photos.app: когда вы щелкаете и увеличиваете масштаб альбома, фотографии появляются в расширяющемся представлении. Этот вид приблизительно центрирован с верхним правом углом на первом пальце и нижним левым пальцем на другом пальце. Я смешал его с распознающим панорамирование, но таким образом пользователь всегда должен зажимать, а затем панорамировать для настройки.

Вот так графическое объяснение, я могу опубликовать видео моего приложения, если это неясно (не секрет, я пытаюсь воспроизвести Photos.app iPad...)

Итак, для начального положения пальцев, начинающего масштабирование:

enter image description here

Это фактический "увеличенный" кадр. Квадрат больше, но положение ниже пальцев.

given the start position

Вот что я хотел бы иметь: тот же размер, но разные origin.x и y:

enter image description here

(извините за свои плохие навыки работы с фотошопом ^^)

4b9b3361

Ответ 1

Вы можете получить CGPoint середины между двумя пальцами через следующий код в методе handlingPinchGesture.

CGPoint point = [sender locationInView:self];

Мой метод handlePinchGesture приведен ниже.

/*
instance variables

CGFloat lastScale;
CGPoint lastPoint;
*/

- (void)handlePinchGesture:(UIPinchGestureRecognizer *)sender {
    if ([sender numberOfTouches] < 2)
        return;

    if (sender.state == UIGestureRecognizerStateBegan) {
        lastScale = 1.0;
        lastPoint = [sender locationInView:self];
    }

    // Scale
    CGFloat scale = 1.0 - (lastScale - sender.scale);
    [self.layer setAffineTransform:
        CGAffineTransformScale([self.layer affineTransform], 
                               scale, 
                               scale)];
    lastScale = sender.scale;

    // Translate
    CGPoint point = [sender locationInView:self];
    [self.layer setAffineTransform:
        CGAffineTransformTranslate([self.layer affineTransform], 
                                   point.x - lastPoint.x, 
                                   point.y - lastPoint.y)];
    lastPoint = [sender locationInView:self];
}

Ответ 2

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

// scale and rotation transforms are applied relative to the layer anchor point
// this method moves a gesture recognizer view anchor point between the user fingers
- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
    if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
        UIView *piece = gestureRecognizer.view;
        CGPoint locationInView = [gestureRecognizer locationInView:piece];
        CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview];

        piece.layer.anchorPoint = CGPointMake(locationInView.x / piece.bounds.size.width, locationInView.y / piece.bounds.size.height);
        piece.center = locationInSuperview;
    }
}

// scale the piece by the current scale
// reset the gesture recognizer rotation to 0 after applying so the next callback is a delta from the current scale
- (void)scalePiece:(UIPinchGestureRecognizer *)gestureRecognizer
{
    [self adjustAnchorPointForGestureRecognizer:gestureRecognizer];

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
        [gestureRecognizer view].transform = CGAffineTransformScale([[gestureRecognizer view] transform], [gestureRecognizer scale], [gestureRecognizer scale]);
        [gestureRecognizer setScale:1];
    }
}