UIImageView手势(缩放、旋转)问题

24

我想对一个UIImageView进行缩放和旋转操作,但我有两个问题:

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

谢谢


我正在尝试在我的应用程序上设置捏合缩放,你能告诉我你代码中的lastScaleFactor是什么吗?非常感谢。 - Hosni
5个回答

64

希望这对你有所帮助,这是我通常实现手势识别的方法:

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

在您的代理中实现gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:即可。

我设置了UIPinchGestureRecognizerUIPanGestureRecognizerUIRotationGestureRecognizer,希望它们同时工作。我还有一个UITapGestureRecognizer,我不希望它同时被识别。我所做的只是这样:

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

    return NO;
}

15

我在斯坦福大学的网站上发现了一些可能会引起您兴趣的内容:

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

在此网站上,您需要向下滚动直到看到数字14:“标题:Lecture #14 - MultiTouch

下载:"14_MultiTouchDemo.zip"

该示例可以同时对所有图像进行缩放和旋转。

希望能对您有所帮助 :)


这个演示不使用UIGestureRecognizer,它解决了触摸的含义。 - Ali El-sayed Ali

3
当您使用CGAffineTransformMakeScale时,每次使用它都会重置Identity的转换,并且您会失去先前的转换信息。
尝试使用CGAffineTransformScale(view.transform,scale,scale)进行捏合缩放。 但是,您需要保留原始框架大小以控制缩放。 参见:如何使用pinch zoom(UIPinchGestureRecognizer)来更改UITextView的宽度? 对于旋转也是类似的:
   if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
        view.transform = CGAffineTransformRotate([view transform], [gestureRecognizer rotation]);
        [gestureRecognizer setRotation:0];
    }

3

我知道这是一个相当古老的帖子,但我发现了这个ImageView子类,它可以很好地实现缩放、旋转和平移。它在ImageView上使用手势识别器。我正在我的一个应用程序中使用它。

ZoomRotatePanImageView


非常感谢,这正是我需要的。 - Marta Rodriguez

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接