iOS捏尺和两个手指同时旋转

这是我的代码:

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

我的轮换自己做得很好,我的规模很大,但他们不会一起工作。 一个总是工作,或另一个不工作。 当我执行shouldRecognizeSimultaneouslyWithGestureRecognizer这两个手势似乎相互对抗,产生不良的结果。 我错过了什么? (是的,我已经实现了<UIGestureRecognizerDelegate>

每次pinch:被调用,你只需要计算基于捏识别器的规模的变换。 每次调用pinchRotate: ,只需根据旋转识别器的旋转来计算变换。 你永远不会把规模和旋转结合成一个变换。

这是一个方法。 给自己一个新的实例variables, _activeRecognizers

 NSMutableSet *_activeRecognizers; 

viewDidLoad初始化它:

 _activeRecognizers = [NSMutableSet set]; 

使用一种方法作为识别器的动作:

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

这工作,如果你只是允许旋转和缩放。 (我甚至testing过!)

如果要添加平移,请使用单独的操作方法,然后调整selectedImage.center 。 试图做旋转和缩放使用selectedImage.transform平移要复杂得多。

为了实现这一点,您需要实现手势委托shouldRecognizeSimultaneouslyWithGestureRecognizer并把你想同时识别什么手势。

 // ensure that the pinch and rotate gesture recognizers on a particular view can all recognize simultaneously // prevent other gesture recognizers from recognizing simultaneously - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { // if the gesture recognizers's view isn't one of our views, don't allow simultaneous recognition if (gestureRecognizer.view != firstView && gestureRecognizer.view != secondView) return NO; // 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; } 

此代码需要修改为您想要同时识别手势的视图。 上面的代码是你需要的。

斯威夫特3与泛,旋转和捏

 // MARK: - Gesturies func transformUsingRecognizer(_ recognizer: UIGestureRecognizer, transform: CGAffineTransform) -> CGAffineTransform { if let rotateRecognizer = recognizer as? UIRotationGestureRecognizer { return transform.rotated(by: rotateRecognizer.rotation) } if let pinchRecognizer = recognizer as? UIPinchGestureRecognizer { let scale = pinchRecognizer.scale return transform.scaledBy(x: scale, y: scale) } if let panRecognizer = recognizer as? UIPanGestureRecognizer { let deltaX = panRecognizer.translation(in: imageView).x let deltaY = panRecognizer.translation(in: imageView).y return transform.translatedBy(x: deltaX, y: deltaY) } return transform } var initialTransform: CGAffineTransform? var gestures = Set<UIGestureRecognizer>(minimumCapacity: 3) @IBAction func processTransform(_ sender: Any) { let gesture = sender as! UIGestureRecognizer switch gesture.state { case .began: if gestures.count == 0 { initialTransform = imageView.transform } gestures.insert(gesture) case .changed: if var initial = initialTransform { gestures.forEach({ (gesture) in initial = transformUsingRecognizer(gesture, transform: initial) }) imageView.transform = initial } case .ended: gestures.remove(gesture) default: break } } func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true }