iOSピンチスケールと2本の指が同時に回転

ここに私のコードです:

viewDidLoad:

UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinch:)];
[self.canvas addGestureRecognizer:pinch];
pinch.delegate = self;

UIRotationGestureRecognizer *twoFingersRotate = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(pinchRotate:)];
[[self canvas] addGestureRecognizer:twoFingersRotate];

twoFingersRotate.delegate = self;

ピンチと回転のコード:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}

-(void)pinchRotate:(UIRotationGestureRecognizer*)rotate
{
    SMImage *selectedImage = [DataCenter sharedDataCenter].selectedImage;

    switch (rotate.state) 
    {
        case UIGestureRecognizerStateBegan:
        {
            selectedImage.referenceTransform = selectedImage.transform;
            break;
        }
        case UIGestureRecognizerStateChanged:
        {
            selectedImage.transform = CGAffineTransformRotate(selectedImage.referenceTransform, ([rotate rotation] * 55) * M_PI/180);
            break;
        }

        default:
            break;
    }
}

-(void)pinch:(UIPinchGestureRecognizer*)pinch
{
    SMImage *selectedImage = [DataCenter sharedDataCenter].selectedImage;
    [self itemSelected];

    switch (pinch.state) 
    {
        case UIGestureRecognizerStateBegan:
        {
            selectedImage.referenceTransform = selectedImage.transform;
            break;
        }
        case UIGestureRecognizerStateChanged:
        {
            CGAffineTransform transform = CGAffineTransformScale(selectedImage.referenceTransform, pinch.scale, pinch.scale);
            selectedImage.transform = transform;
            break;
        }

        default:
            break;
    }
}

My rotation works great on its own and my scale works great on
its own, but they wont work together. One always works or the other
doesn’t. When I implement
shouldRecognizeSimultaneouslyWithGestureRecognizer the two gestures
seem to fight against each other and produce poor results. What am
I missing? (Yes I have implemented )

ベストアンサー

pinch:が呼び出されるたびに、ピンチレコグナイザのスケールに基づいてトランスフォームを計算するだけです。
pinchRotate:が呼び出されるたびに、回転認識器の回転に基づいて変換を計算するだけです。スケールと回転を1つの変換に結合することは決してありません。

ここにアプローチがあります。新しいインスタンス変数 _activeRecognizers
を1つ与えてください。

NSMutableSet *_activeRecognizers;

viewDidLoad で初期化してください:

_activeRecognizers = [NSMutableSet set];

両方のレコグナイザのアクションとして、1つの方法を使用します。

- (IBAction)handleGesture:(UIGestureRecognizer *)recognizer
{
    SMImage *selectedImage = [DataCenter sharedDataCenter].selectedImage;

    switch (recognizer.state) {
        case UIGestureRecognizerStateBegan:
            if (_activeRecognizers.count == 0)
                selectedImage.referenceTransform = selectedImage.transform;
            [_activeRecognizers addObject:recognizer];
            break;

        case UIGestureRecognizerStateEnded:
            selectedImage.referenceTransform = [self applyRecognizer:recognizer toTransform:selectedImage.referenceTransform];
            [_activeRecognizers removeObject:recognizer];
            break;

        case UIGestureRecognizerStateChanged: {
            CGAffineTransform transform = selectedImage.referenceTransform;
            for (UIGestureRecognizer *recognizer in _activeRecognizers)
                transform = [self applyRecognizer:recognizer toTransform:transform];
            selectedImage.transform = transform;
            break;
        }

        default:
            break;
    }
}

このヘルパーメソッドが必要です:

- (CGAffineTransform)applyRecognizer:(UIGestureRecognizer *)recognizer toTransform:(CGAffineTransform)transform
{
    if ([recognizer respondsToSelector:@selector(rotation)])
        return CGAffineTransformRotate(transform, [(UIRotationGestureRecognizer *)recognizer rotation]);
    else if ([recognizer respondsToSelector:@selector(scale)]) {
        CGFloat scale = [(UIPinchGestureRecognizer *)recognizer scale];
        return CGAffineTransformScale(transform, scale, scale);
    }
    else
        return transform;
}

これは回転とスケーリングだけを許可している場合に機能します。 (私はそれをテストしました!)

パンを追加する場合は、別のアクションメソッドを使用し、 selectedImage.center
を調整してください。 selectedImage.transform
を使用して回転とスケーリングでパンをしようとすると、はるかに複雑になります。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です