icon guidelines font blue apple iphone ios objective-c ipad cocoa-touch

iphone - blue - ios guidelines font



iOS Pinch Scale y Two Finger giran al mismo tiempo (3)

Aquí está mi código:

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;

Código para pellizcos y rotaciones:

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

Mi rotación funciona muy bien por sí misma y mi báscula funciona muy bien por sí misma, pero no funcionarán juntas. Uno siempre funciona o el otro no. Cuando implemento shouldRecognizeSimultaneouslyWithGestureRecognizer, los dos gestos parecen luchar unos contra otros y producen resultados pobres. ¿Qué me estoy perdiendo? (Sí, he implementado <UIGestureRecognizerDelegate> )


Cada vez que se pinch: , simplemente calcula la transformación en función de la escala del reconocedor de pellizco. Cada vez que se pinchRotate: simplemente calcula la transformación en función de la rotación del reconocedor de rotación. Nunca combine la escala y la rotación en una sola transformación.

Aquí hay un enfoque. Date una nueva variable de instancia, _activeRecognizers :

NSMutableSet *_activeRecognizers;

viewDidLoad en viewDidLoad :

_activeRecognizers = [NSMutableSet set];

Use un método como acción para ambos reconocedores:

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

Necesitarás este método de ayuda:

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

Esto funciona si solo permite girar y escalar. (¡Incluso lo probé!)

Si desea agregar panoramización, use un método de acción separado y simplemente ajuste selectedImage.center . Intentar hacer panorámicas con rotación y escalado utilizandoImage.transform selectedImage.transform es mucho más complicado.


Para que esto suceda, debe implementar el delegado de gestos shouldRecognizeSimultaneouslyWithGestureRecognizer y colocar los gestos que desea reconocer simultáneamente.

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

Este código debe modificarse para la vista para la que desee reconocer los gestos de forma simultánea. El código anterior es lo que necesitas.


Swift 3 con Pan, Girar y Pellizcar

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