UIImageView Gestures (Zoom, Rotate) Вопрос - PullRequest
24 голосов
/ 10 августа 2010

Я хотел бы сделать 2 операции для увеличения или поворота UIImageView, у меня 2 проблемы:

A. Я делаю операцию увеличения для напр. и когда я пытаюсь сделать поворот, UIImageView устанавливается в исходный размер, я хотел бы знать, как сохранить увеличенное изображение UIImageView и сделать поворот из увеличенного изображения.

B. Я хотел бы объединить операцию масштабирования с вращением, и я не знаю, как это реализовать:

- (void)viewDidLoad 
{
    foo = [[UIImageView alloc]initWithFrame:CGRectMake(100.0, 100.0, 600, 800.0)];
    foo.userInteractionEnabled = YES;
    foo.multipleTouchEnabled  = YES;
    foo.image = [UIImage imageNamed:@"earth.jpg"];
    foo.contentMode = UIViewContentModeScaleAspectFit;
    foo.clipsToBounds = YES;

    [self.view addSubview:foo];
}

//---pinch gesture--- 
UIPinchGestureRecognizer *pinchGesture =
[[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinchGesture:)];
[foo addGestureRecognizer:pinchGesture]; 
[pinchGesture release];

//---rotate gesture--- 
UIRotationGestureRecognizer *rotateGesture =
[[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotateGesture:)];
[foo addGestureRecognizer:rotateGesture]; 
[rotateGesture release];

//---handle pinch gesture--- 
-(IBAction) handlePinchGesture:(UIGestureRecognizer *) sender {
    NSLog(@"Pinch");
    CGFloat factor = [(UIPinchGestureRecognizer *) sender scale];
    if (factor > 1) { 
        //---zooming in--- 
        sender.view.transform = CGAffineTransformMakeScale(
                                                           lastScaleFactor + (factor-1),
                                                           lastScaleFactor + (factor-1)); 
    } 
    else {
        //---zooming out--- 
        sender.view.transform = CGAffineTransformMakeScale(lastScaleFactor * factor, lastScaleFactor * factor);
    }
    if (sender.state == UIGestureRecognizerStateEnded) { 
        if (factor > 1) {
            lastScaleFactor += (factor-1); 
        } else {
            lastScaleFactor *= factor;
        }
    }
}

//---handle rotate gesture--- 
-(IBAction) handleRotateGesture:(UIGestureRecognizer *) sender {
    CGFloat rotation = [(UIRotationGestureRecognizer *) sender rotation]; 
    CGAffineTransform transform = CGAffineTransformMakeRotation(rotation + netRotation); 
    sender.view.transform = transform;
    if (sender.state == UIGestureRecognizerStateEnded) { 
        netRotation += rotation;
    }
}

Спасибо

Ответы [ 5 ]

63 голосов
/ 29 августа 2011

Надеюсь, что это может быть полезно для вас, вот как я обычно реализую распознаватели жестов:

UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotatePiece:)];
[piece addGestureRecognizer:rotationGesture];
[rotationGesture release];

UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scalePiece:)];
[pinchGesture setDelegate:self];
[piece addGestureRecognizer:pinchGesture];
[pinchGesture release];

Метод поворота: после применения поверните распознаватель жестов на 0, чтобы следующий обратный вызов был дельтой от текущеговращение

- (void)rotatePiece:(UIRotationGestureRecognizer *)gestureRecognizer {
    [self adjustAnchorPointForGestureRecognizer:gestureRecognizer];

    if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
        [gestureRecognizer view].transform = CGAffineTransformRotate([[gestureRecognizer view] transform], [gestureRecognizer rotation]);
        [gestureRecognizer setRotation:0];
    }
}

Метод масштабирования, в конце сбросьте масштаб распознавателя жестов на 1 после применения, чтобы следующий обратный вызов представлял собой дельту от текущей шкалы

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

, чем убедитесь, что щепоткавсе средства распознавания жестов, панорамирования и поворота в определенном представлении могут одновременно распознавать другие распознаватели жестов, что не позволяет одновременно распознавать другие распознаватели жестов

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
// if the gesture recognizers are on different views, don't allow simultaneous recognition
if (gestureRecognizer.view != otherGestureRecognizer.view)
    return NO;

// if either of the gesture recognizers is the long press, don't allow simultaneous recognition
if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] || [otherGestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]])
    return NO;

    return YES;
}

Преобразования масштаба и поворота применяются относительно точки привязки слоя. Этот метод перемещает привязку представления распознавателя жестов.точка между пальцами пользователя

- (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;
    }
}
16 голосов
/ 01 августа 2011

Просто внедрите жестRecognizer: shouldRecognizeSim одновременноuallyWithGestureRecognizer: в своем делегате.

У меня настроены UIPinchGestureRecognizer, UIPanGestureRecognizer и UIRotationGestureRecognizer, и я хочу, чтобы все они работали одновременно.У меня также есть UITapGestureRecognizer, который я не хочу распознать одновременно.Все, что я сделал, это:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if (![gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] && ![otherGestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
        return YES;
    }

    return NO;
}
15 голосов
/ 11 августа 2010

На сайте Стэнфордского университета я нашел кое-что, что может вас заинтересовать:

http://www.stanford.edu/class/cs193p/cgi-bin/drupal/downloads-2010-winter

на этом сайте вам нужно будет прокрутить вниз, пока не появится число 14: « Название: Лекция № 14 - MultiTouch»

Скачать: "14_MultiTouchDemo.zip"

В этом примере вы можете масштабировать и поворачивать каждое изображение одновременно.

надеюсь, я помог:)

3 голосов
/ 21 ноября 2010

Когда вы используете CGAffineTransformMakeScale, вы сбрасываете преобразование Identity каждый раз, когда используете его, и теряете предыдущую информацию о преобразовании.

Попробуйте использовать CGAffineTransformScale(view.transform,scale, scale) для масштабирования.Вам нужно будет сохранить исходный размер кадра, чтобы контролировать масштабирование.
см .: Как я могу использовать масштабирование (UIPinchGestureRecognizer) для изменения ширины UITextView?

Для вращения аналогично:

   if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
        view.transform = CGAffineTransformRotate([view transform], [gestureRecognizer rotation]);
        [gestureRecognizer setRotation:0];
    }
2 голосов
/ 31 августа 2015

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

ZoomRotatePanImageView

...