web-dev-qa-db-ja.com

UIImageViewジェスチャー(ズーム、回転)に関する質問

UIImageViewズーム、回転に対して2つの操作を行いたいのですが、2つの問題があります。

A。 exのズーム操作をします。 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;
    }
}

ありがとう

24
john Stilkowicz

これがあなたに役立つことを願っています、それが私が通常ジェスチャー認識機能を実装する方法です:

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

Rotateメソッド:次のコールバックが現在の回転からのデルタになるように、適用後にジェスチャー認識機能の回転を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;
    }
}
63

デリゲートに gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: を実装するだけです。

UIPinchGestureRecognizerUIPanGestureRecognizer、およびUIRotationGestureRecognizerをセットアップしており、それらすべてを同時に機能させたい。また、同時に認識したいしないUITapGestureRecognizerもあります。私がしたことはこれだけでした:

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

    return NO;
}
16

スタンフォード大学のウェブサイトであなたが興味を持つかもしれないものを見つけました:

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

このサイトでは、番号14が表示されるまで下にスクロールする必要があります。「タイトル:講義#14-マルチタッチ」

ダウンロード: "14_MultiTouchDemo.Zip"

この例では、すべての画像を同時にスケーリングおよび回転できます。

私が助けてくれれば幸いです:)

15
DailyDoggy

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];
    }
3
Steven Veltema

これはかなり古いスレッドであることを知っています。このimageviewサブクラスに出くわしました。これは、ズーム、回転、パンに適しています。 imageviewでジェスチャー認識機能を使用します。私はこれを私のアプリの1つに使用しています。

ZoomRotatePanImageView

2
anoop4real