UIGestureRecognizer en UIImageView

Tengo un UIImageView , que quiero poder cambiar de tamaño y girar, etc.

¿ UIGestureRecognizer puede agregar un UIGestureRecognizer al UIImageView ?

Me gustaría agregar un reconocedor rotar y pellizcar a un UIImageView que se crearía en tiempo de ejecución.

¿Cómo se puede agregar estos reconocedores?

Verifique que userInteractionEnabled sea YES en UIImageView . Luego puede agregar un reconocedor de gestos.

 imageView.userInteractionEnabled = YES; UIPinchGestureRecognizer *pgr = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)]; pgr.delegate = self; [imageView addGestureRecognizer:pgr]; [pgr release]; : : - (void)handlePinch:(UIPinchGestureRecognizer *)pinchGestureRecognizer { //handle pinch... } 

Sí, se puede agregar un UIGestureRecognizer a UIImageView. Como se indicó en la otra respuesta, es muy importante recordar habilitar la interacción del usuario en la vista de imagen estableciendo su propiedad userInteractionEnabled en YES . UIImageView hereda de UIView, cuya propiedad de interacción con el usuario está establecida en YES de manera predeterminada, sin embargo, la propiedad de interacción del usuario de UIImageView está establecida en NO de manera predeterminada.

De los documentos de UIImageView:

Los nuevos objetos de vista de imagen están configurados para ignorar los eventos del usuario de forma predeterminada. Si desea manejar eventos en una subclase personalizada de UIImageView, debe cambiar explícitamente el valor de la propiedad userInteractionEnabled a YES después de inicializar el objeto.

De todos modos, en la mayor parte de la respuesta. Aquí hay un ejemplo de cómo crear un UIImageView con un UIPinchGestureRecognizer , un UIRotationGestureRecognizer y un UIPanGestureRecognizer .

Primero, en viewDidLoad u otro método de su elección, cree una vista de imagen, viewDidLoad una imagen, un marco y habilite la interacción del usuario. Luego crea los tres gestos de la siguiente manera. Asegúrese de utilizar su propiedad de delegado (lo más probable es que se establezca en sí mismo). Esto requerirá usar múltiples gestos al mismo tiempo.

 - (void)viewDidLoad { [super viewDidLoad]; // set up the image view UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"someImage"]]; [imageView setBounds:CGRectMake(0.0, 0.0, 120.0, 120.0)]; [imageView setCenter:self.view.center]; [imageView setUserInteractionEnabled:YES]; // <--- This is very important // create and configure the pinch gesture UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGestureDetected:)]; [pinchGestureRecognizer setDelegate:self]; [imageView addGestureRecognizer:pinchGestureRecognizer]; // create and configure the rotation gesture UIRotationGestureRecognizer *rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationGestureDetected:)]; [rotationGestureRecognizer setDelegate:self]; [imageView addGestureRecognizer:rotationGestureRecognizer]; // creat and configure the pan gesture UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureDetected:)]; [panGestureRecognizer setDelegate:self]; [imageView addGestureRecognizer:panGestureRecognizer]; [self.view addSubview:imageView]; // add the image view as a subview of the view controllers view } 

Estos son los tres métodos que se invocarán cuando se detecten los gestos en su vista. Dentro de ellos, comprobaremos el estado actual del gesto, y si está en UIGestureRecognizerState comenzado o cambiado, leeremos la propiedad de escala / rotación / traducción del gesto, aplicaremos esa información a una transformación afín, aplicaremos la transformación afín al vista de imagen, y luego restablecer la escala / rotación / traducción de los gestos.

 - (void)pinchGestureDetected:(UIPinchGestureRecognizer *)recognizer { UIGestureRecognizerState state = [recognizer state]; if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged) { CGFloat scale = [recognizer scale]; [recognizer.view setTransform:CGAffineTransformScale(recognizer.view.transform, scale, scale)]; [recognizer setScale:1.0]; } } - (void)rotationGestureDetected:(UIRotationGestureRecognizer *)recognizer { UIGestureRecognizerState state = [recognizer state]; if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged) { CGFloat rotation = [recognizer rotation]; [recognizer.view setTransform:CGAffineTransformRotate(recognizer.view.transform, rotation)]; [recognizer setRotation:0]; } } - (void)panGestureDetected:(UIPanGestureRecognizer *)recognizer { UIGestureRecognizerState state = [recognizer state]; if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged) { CGPoint translation = [recognizer translationInView:recognizer.view]; [recognizer.view setTransform:CGAffineTransformTranslate(recognizer.view.transform, translation.x, translation.y)]; [recognizer setTranslation:CGPointZero inView:recognizer.view]; } } 

Finalmente, y muy importante, deberá utilizar el método gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer de gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer para permitir que los gestos funcionen al mismo tiempo. Si estos tres gestos son los únicos tres gestos que tienen asignada esta clase como su delegado, entonces simplemente puede devolver YES como se muestra a continuación. Sin embargo, si tiene gestos adicionales que tienen esta clase asignada como su delegado, puede que necesite agregar lógica a este método para determinar qué gesto es el que antes de permitir que todos trabajen juntos.

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

No olvide asegurarse de que su clase cumpla con el protocolo UIGestureRecognizerDelegate . Para hacerlo, asegúrese de que su interfaz se vea más o menos así:

 @interface MyClass : MySuperClass  

Si prefiere jugar con el código en un proyecto de ejemplo que esté trabajando, el proyecto de ejemplo que he creado que contiene este código se puede encontrar aquí.

Solución Swift 2.0

Usted crea un reconocedor de gestos de tocar, pellizcar o deslizar en la misma casa. A continuación, le guiaré a través de 4 pasos para poner en marcha su reconocedor.

4 pasos

1.) Heredar de UIGestureRecognizerDelegate agregándolo a la firma de su clase.

 class ViewController: UIViewController, UIGestureRecognizerDelegate {...} 

2.) Controle el arrastre de su imagen a su viewController para crear una IBOutlet:

 @IBOutlet weak var tapView: UIImageView! 

3.) En su viewDidLoad agregue el siguiente código:

 // create an instance of UITapGestureRecognizer and tell it to run // an action we'll call "handleTap:" let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) // we use our delegate tap.delegate = self // allow for user interaction tapView.userInteractionEnabled = true // add tap as a gestureRecognizer to tapView tapView.addGestureRecognizer(tap) 

4.) Cree la función que se invocará cuando se toque su reconocedor de gestos. (Puede excluir el = nil si elige).

 func handleTap(sender: UITapGestureRecognizer? = nil) { // just creating an alert to prove our tap worked! let tapAlert = UIAlertController(title: "hmmm...", message: "this actually worked?", preferredStyle: UIAlertControllerStyle.Alert) tapAlert.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil)) self.presentViewController(tapAlert, animated: true, completion: nil) } 

Tu código final debería verse más o menos así:

 class ViewController: UIViewController, UIGestureRecognizerDelegate { @IBOutlet weak var tapView: UIImageView! override func viewDidLoad() { super.viewDidLoad() let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:")) tap.delegate = self tapView.userInteractionEnabled = true tapView.addGestureRecognizer(tap) } func handleTap(sender: UITapGestureRecognizer? = nil) { let tapAlert = UIAlertController(title: "hmmm...", message: "this actually worked?", preferredStyle: UIAlertControllerStyle.Alert) tapAlert.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil)) self.presentViewController(tapAlert, animated: true, completion: nil) } } 

Swift 4

 myImageView.isUserInteractionEnabled = true let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector(("imageTapped:"))) tapGestureRecognizer.numberOfTapsRequired = 1 myImageView.addGestureRecognizer(tapGestureRecognizer) 

y cuando se toca:

 func imageTapped(sender: UITapGestureRecognizer) { // do something when image tapped println("image tapped") } 

para los amantes de Swift:

  myImageView.userInteractionEnabled = true var tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "imageTapped:") tapGestureRecognizer.numberOfTapsRequired = 1 myImageView.addGestureRecognizer(tapGestureRecognizer) 

luego cuando se tocó la imagen:

 func imageTapped(sender: UITapGestureRecognizer) { // do something when image tapped println("image tapped") } 

Ejemplo de SWIFT 3

 override func viewDidLoad() { self.backgroundImageView.addGestureRecognizer( UITapGestureRecognizer.init(target: self, action: #selector(didTapImageview(_:)) ) ) self.backgroundImageView.isUserInteractionEnabled = true } func didTapImageview(_ sender: Any) { // do something } } 

Ningún Reconciliador de gestos delega u otras implementaciones cuando sea necesario.

Acabo de hacer esto con swift4 agregando 3 gestos juntos en vista única

  1. UIPinchGestureRecognizer : acercar y alejar la vista.
  2. UIRotationGestureRecognizer : Gire la vista.
  3. UIPanGestureRecognizer : Arrastrando la vista.

Aquí mi código de muestra

 class ViewController: UIViewController: UIGestureRecognizerDelegate{ //your image view that outlet from storyboard or xibs file. @IBOutlet weak var imgView: UIImageView! // declare gesture recognizer var panRecognizer: UIPanGestureRecognizer? var pinchRecognizer: UIPinchGestureRecognizer? var rotateRecognizer: UIRotationGestureRecognizer? override func viewDidLoad() { super.viewDidLoad() // Create gesture with target self(viewcontroller) and handler function. self.panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(self.handlePan(recognizer:))) self.pinchRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(self.handlePinch(recognizer:))) self.rotateRecognizer = UIRotationGestureRecognizer(target: self, action: #selector(self.handleRotate(recognizer:))) //delegate gesture with UIGestureRecognizerDelegate pinchRecognizer?.delegate = self rotateRecognizer?.delegate = self panRecognizer?.delegate = self // than add gesture to imgView self.imgView.addGestureRecognizer(panRecognizer!) self.imgView.addGestureRecognizer(pinchRecognizer!) self.imgView.addGestureRecognizer(rotateRecognizer!) } // handle UIPanGestureRecognizer @objc func handlePan(recognizer: UIPanGestureRecognizer) { let gview = recognizer.view if recognizer.state == .began || recognizer.state == .changed { let translation = recognizer.translation(in: gview?.superview) gview?.center = CGPoint(x: (gview?.center.x)! + translation.x, y: (gview?.center.y)! + translation.y) recognizer.setTranslation(CGPoint.zero, in: gview?.superview) } } // handle UIPinchGestureRecognizer @objc func handlePinch(recognizer: UIPinchGestureRecognizer) { if recognizer.state == .began || recognizer.state == .changed { recognizer.view?.transform = (recognizer.view?.transform.scaledBy(x: recognizer.scale, y: recognizer.scale))! recognizer.scale = 1.0 } } // handle UIRotationGestureRecognizer @objc func handleRotate(recognizer: UIRotationGestureRecognizer) { if recognizer.state == .began || recognizer.state == .changed { recognizer.view?.transform = (recognizer.view?.transform.rotated(by: recognizer.rotation))! recognizer.rotation = 0.0 } } // mark sure you override this function to make gestures work together func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } } 

Cualquier pregunta, solo escriba para comentar. gracias

También puede arrastrar un reconocedor de gesto de toque a la vista de imagen en Storyboard. A continuación, crea una acción mediante Ctrl + arrastre al código …

Para los amantes de Blocks, puedes usar ALActionBlocks para agregar acción de gestos en bloque

 __weak ALViewController *wSelf = self; imageView.userInteractionEnabled = YES; UITapGestureRecognizer *gr = [[UITapGestureRecognizer alloc] initWithBlock:^(UITapGestureRecognizer *weakGR) { NSLog(@"pan %@", NSStringFromCGPoint([weakGR locationInView:wSelf.view])); }]; [self.imageView addGestureRecognizer:gr];