这是我的代码:
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>
)
答案 0 :(得分:34)
每次调用pinch:
时,您只需根据捏合识别器的比例计算变换。每次调用pinchRotate:
时,您只需根据旋转识别器的旋转计算变换。您永远不会将比例和旋转合并为一个变换。
这是一种方法。给自己一个新的实例变量_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;
}
如果你只是允许旋转和缩放,这是有效的。 (我甚至测试过它!)
如果要添加平移,请使用单独的操作方法,然后调整selectedImage.center
。尝试使用selectedImage.transform
进行旋转和缩放平移要复杂得多。
答案 1 :(得分:8)
为此,您需要实现手势委托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;
}
此代码需要修改为您想要同步手势识别器的视图。上面的代码就是你需要的。
答案 2 :(得分:7)
Swift 3 with Pan,Rotate and Pinch
// 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
}