UIPinchGestureRecognizer. Увеличьте расположение пальцев, а не только центр

Я могу использовать UIPinchGestureRecognizer для увеличения в представлении UICollectionViewCell, но это не имеет значения, место, где вы начинаете делать UIPinch жестом, всегда зум идет в центре вида. Например, я хотел бы ущипнуть в левой верхней части вида, и масштаб должен быть создан в месте, где я касаюсь экрана. Но если я сделаю это, масштаб будет создан в центре вида.

Это код, который я использую для увеличения:

 if([gesture state] == UIGestureRecognizerStateBegan) {
        previousScale = 1.0;

    }

    if (
        [gesture state] == UIGestureRecognizerStateChanged) {

        CGFloat currentScale = [[[gesture view].layer valueForKeyPath:@"transform.scale"] floatValue];

        // Constants to adjust the max/min values of zoom
        const CGFloat kMaxScale = 4.0;
        const CGFloat kMinScale = 1.0;

        CGFloat newScale = 1 -  (previousScale - [gesture scale]); // new scale is in the range (0-1)
        newScale = MIN(newScale, kMaxScale / currentScale);
        newScale = MAX(newScale, kMinScale / currentScale);
        scale = newScale;

        CGAffineTransform transform = CGAffineTransformScale([[gesture view] transform], newScale, newScale);

        [gesture view].transform = transform;

        [self.collectionView.collectionViewLayout invalidateLayout];
    }

Итак, как я могу выбрать позицию UIPinchGesture?

Спасибо

2 ответа

Решение

Вы применяете только масштабное преобразование, которое всегда будет держать вид в центре. Помимо масштабирования, вы также должны выполнить перевод на основе locationInView, Вы можете заменить вышеуказанную функцию следующим кодом:

- (void)handlePinchGesture:(UIPinchGestureRecognizer *)sender {


    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];
}

Я сделал это, это мой окончательный код:

if([gesture state] == UIGestureRecognizerStateBegan) {
    previousScale = 1.0;
    lastPoint = [gesture locationInView:[gesture view]];
}

if (
    [gesture state] == UIGestureRecognizerStateChanged) {

    CGFloat currentScale = [[[gesture view].layer valueForKeyPath:@"transform.scale"] floatValue];

    // Constants to adjust the max/min values of zoom
    const CGFloat kMaxScale = 4.0;
    const CGFloat kMinScale = 1.0;

    CGFloat newScale = 1 -  (previousScale - [gesture scale]); // new scale is in the range (0-1)
    newScale = MIN(newScale, kMaxScale / currentScale);
    newScale = MAX(newScale, kMinScale / currentScale);
    scale = newScale;

    CGAffineTransform transform = CGAffineTransformScale([[gesture view] transform], newScale, newScale);

    [gesture view].transform = transform;

    CGPoint point = [gesture locationInView:[gesture view]];
    CGAffineTransform transformTranslate = CGAffineTransformTranslate([[gesture view] transform], point.x-lastPoint.x, point.y-lastPoint.y);

    [gesture view].transform = transformTranslate;
}
Другие вопросы по тегам