ここに私のコードです:
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
を使用して回転とスケーリングでパンをしようとすると、はるかに複雑になります。