¿Cómo agregar un evento táctil a una UIView?

¿Cómo agrego un evento táctil a una UIView?
Lo bash:

UIView *headerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, nextY)] autorelease]; [headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown]; // ERROR MESSAGE: UIView may not respond to '-addTarget:action:forControlEvents:' 

No quiero crear una subclass y sobrescribir

 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 

En iOS 3.2 y superior, puedes usar reconocedores de gestos. Por ejemplo, así es como manejarías un evento tap:

 //The setup code (in viewDidLoad in your view controller) UITapGestureRecognizer *singleFingerTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)]; [self.view addGestureRecognizer:singleFingerTap]; //The event handling method - (void)handleSingleTap:(UITapGestureRecognizer *)recognizer { CGPoint location = [recognizer locationInView:[recognizer.view superview]]; //Do stuff here... } 

También hay un montón de gestos incorporados. Consulte la documentation para el event handling events de iOS y UIGestureRecognizer . También tengo un montón de código de ejemplo en github que podría ayudar.

Reconocedores de gestos

Hay varios events táctiles de uso común (o gestos) de los que se le puede notificar cuando agrega un Gesture Recognizer a su vista. Los siguientes types de gestos son compatibles de forma pnetworkingeterminada:

  • UITapGestureRecognizer Toque (toque la pantalla brevemente una o más veces)
  • UILongPressGestureRecognizer largo (tocando la pantalla durante mucho time)
  • UIPanGestureRecognizer Pan (mover el dedo por la pantalla)
  • UISwipeGestureRecognizer (mover el dedo rápidamente)
  • UIPinchGestureRecognizer Pellizcar (mover dos dedos juntos o separados, generalmente para hacer zoom)
  • UIRotationGestureRecognizer Gire (moviendo dos dedos en una dirección circular)

Además de estos, también puede crear su propio reconocedor de gestos personalizado.

Agregar un gesto en el generador de interfaces

Arrastre un reconocimiento de gestos desde la biblioteca de objects a su vista.

introduzca la descripción de la imagen aquí

Controle el arrastre del gesto en el Esquema del documento al código del Controlador de vista para crear un Outlet y una Acción.

introduzca la descripción de la imagen aquí

Agregando un gesto mediante progtwigción

Para agregar un gesto mediante progtwigción, usted (1) crea un reconocimiento de gestos, (2) lo agrega a una vista y (3) crea un método que se llama cuando se reconoce el gesto.

 import UIKit class ViewController: UIViewController { @IBOutlet weak var myView: UIView! override func viewDidLoad() { super.viewDidLoad() // 1. create a gesture recognizer (tap gesture) let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:))) // 2. add the gesture recognizer to a view myView.addGestureRecognizer(tapGesture) } // 3. this method is called when a tap is recognized func handleTap(sender: UITapGestureRecognizer) { print("tap") } } 

Notas

  • El parámetro del sender es opcional. Si no necesita una reference al gesto, puede dejarlo fuera. Sin embargo, si lo hace, quite el (_:) después del nombre del método de acción al crear el gesto.
  • El nombre del método handleTap fue arbitrario. action: #selector( someMethodName (sender:)) lo que quiera con la action: #selector( someMethodName (sender:)) .

Más ejemplos

Puede estudiar los reconocedores de gestos que agregué a estas vistas para ver cómo funcionan.

introduzca la descripción de la imagen aquí

Aquí está el código para ese proyecto:

 import UIKit class ViewController: UIViewController { @IBOutlet weak var tapView: UIView! @IBOutlet weak var doubleTapView: UIView! @IBOutlet weak var longPressView: UIView! @IBOutlet weak var panView: UIView! @IBOutlet weak var swipeView: UIView! @IBOutlet weak var pinchView: UIView! @IBOutlet weak var rotateView: UIView! @IBOutlet weak var label: UILabel! override func viewDidLoad() { super.viewDidLoad() // Tap let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap)) tapView.addGestureRecognizer(tapGesture) // Double Tap let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap)) doubleTapGesture.numberOfTapsRequinetworking = 2 doubleTapView.addGestureRecognizer(doubleTapGesture) // Long Press let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress(gesture:))) longPressView.addGestureRecognizer(longPressGesture) // Pan let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(gesture:))) panView.addGestureRecognizer(panGesture) // Swipe (right and left) let swipeRightGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(gesture:))) let swipeLeftGesture = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe(gesture:))) swipeRightGesture.direction = UISwipeGestureRecognizerDirection.right swipeLeftGesture.direction = UISwipeGestureRecognizerDirection.left swipeView.addGestureRecognizer(swipeRightGesture) swipeView.addGestureRecognizer(swipeLeftGesture) // Pinch let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(handlePinch(gesture:))) pinchView.addGestureRecognizer(pinchGesture) // Rotate let rotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(handleRotate(gesture:))) rotateView.addGestureRecognizer(rotateGesture) } // Tap action func handleTap() { label.text = "Tap recognized" // example task: change background color if tapView.backgroundColor == UIColor.blue { tapView.backgroundColor = UIColor.networking } else { tapView.backgroundColor = UIColor.blue } } // Double tap action func handleDoubleTap() { label.text = "Double tap recognized" // example task: change background color if doubleTapView.backgroundColor == UIColor.yellow { doubleTapView.backgroundColor = UIColor.green } else { doubleTapView.backgroundColor = UIColor.yellow } } // Long press action func handleLongPress(gesture: UILongPressGestureRecognizer) { label.text = "Long press recognized" // example task: show an alert if gesture.state == UIGestureRecognizerState.began { let alert = UIAlertController(title: "Long Press", message: "Can I help you?", prefernetworkingStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) self.present(alert, animated: true, completion: nil) } } // Pan action func handlePan(gesture: UIPanGestureRecognizer) { label.text = "Pan recognized" // example task: drag view let location = gesture.location(in: view) // root view panView.center = location } // Swipe action func handleSwipe(gesture: UISwipeGestureRecognizer) { label.text = "Swipe recognized" // example task: animate view off screen let originalLocation = swipeView.center if gesture.direction == UISwipeGestureRecognizerDirection.right { UIView.animate(withDuration: 0.5, animations: { self.swipeView.center.x += self.view.bounds.width }, completion: { (value: Bool) in self.swipeView.center = originalLocation }) } else if gesture.direction == UISwipeGestureRecognizerDirection.left { UIView.animate(withDuration: 0.5, animations: { self.swipeView.center.x -= self.view.bounds.width }, completion: { (value: Bool) in self.swipeView.center = originalLocation }) } } // Pinch action func handlePinch(gesture: UIPinchGestureRecognizer) { label.text = "Pinch recognized" if gesture.state == UIGestureRecognizerState.changed { let transform = CGAffineTransform(scaleX: gesture.scale, y: gesture.scale) pinchView.transform = transform } } // Rotate action func handleRotate(gesture: UIRotationGestureRecognizer) { label.text = "Rotate recognized" if gesture.state == UIGestureRecognizerState.changed { let transform = CGAffineTransform(rotationAngle: gesture.rotation) rotateView.transform = transform } } } 

Notas

  • Puede agregar varios reconocedores de gestos a una sola vista. En aras de la simplicidad, sin embargo, no hice eso (excepto por el gesto de deslizar). Si necesita para su proyecto, debe leer la documentation del reconocedor de gestos . Es bastante comprensible y útil.
  • Problemas conocidos con mis ejemplos anteriores: (1) La vista Panorámica restablece su marco en el siguiente evento de gestos. (2) La vista de deslizamiento proviene de la dirección incorrecta en el primer deslizamiento. (Estos errores en mis ejemplos no deberían afectar su comprensión de cómo funcionan los Reconocedores de gestos.)

Actualizado para Swift 3

Creo que puedes simplemente usar

 UIControl *headerView = ... [headerView addTarget:self action:@selector(myEvent:) forControlEvents:UIControlEventTouchDown]; 

Me refiero a headerView se extiende desde UIControl.

Según la respuesta aceptada , puede definir una macro:

 #define handle_tap(view, delegate, selector) do {\ view.userInteractionEnabled = YES;\ [view addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget:delegate action:selector]];\ } while(0) 

Esta macro usa ARC, por lo que no hay llamada de release .

Ejemplo de uso de macro:

 handle_tap(userpic, self, @selector(onTapUserpic:)); 

Puede lograr esto agregando Gesture Recogniser en su código.

Paso 1: ViewController.m:

 // Declare the Gesture. UITapGestureRecognizer *gesRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; gesRecognizer.delegate = self; // Add Gesture to your view. [yourView addGestureRecognizer:gesRecognizer]; 

Paso 2: ViewController.m:

 // Declare the Gesture Recogniser handler method. - (void)handleTap:(UITapGestureRecognizer *)gestureRecognizer{ NSLog(@"Tapped"); } 

NOTA: aquí yourView en mi caso fue @property (strong, nonatomic) IBOutlet UIView *localView;

EDIT: * localView es el cuadro blanco en Main.storyboard desde abajo

introduzca la descripción de la imagen aquí

introduzca la descripción de la imagen aquí

Heres una versión Swift:

 // MARK: Gesture Extensions extension UIView { func addTapGesture(#tapNumber: Int, target: AnyObject, action: Selector) { let tap = UITapGestureRecognizer (target: target, action: action) tap.numberOfTapsRequinetworking = tapNumber addGestureRecognizer(tap) userInteractionEnabled = true } func addTapGesture(#tapNumber: Int, action: ((UITapGestureRecognizer)->())?) { let tap = BlockTap (tapCount: tapNumber, fingerCount: 1, action: action) addGestureRecognizer(tap) userInteractionEnabled = true } } 

Actualización Swift 3

 import UIKit extension UIView { func addTapGesture(tapNumber : Int, target: Any , action : Selector) { let tap = UITapGestureRecognizer(target: target, action: action) tap.numberOfTapsRequinetworking = tapNumber addGestureRecognizer(tap) isUserInteractionEnabled = true } } 

Utilizar

  yourView.addTapGesture(tapNumber: 1, target: self, action: #selector(yourMethod)) 

Aquí está ios tapgesture; Primero debe crear una acción para GestureRecognizer después de escribir el código siguiente debajo de la acción como se muestra a continuación

 - (IBAction)tapgesture:(id)sender { [_password resignFirstResponder]; [_username resignFirstResponder]; NSLog(@" TapGestureRecognizer tapped"); } 

Otra forma es agregar un button transparente a la vista

 UIButton *b = [UIButton buttonWithType:UIButtonTypeCustom]; b.frame = CGRectMake(0, 0, headerView.width, headerView.height); [headerView addSubview:b]; [b addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchDown]; 

Y luego, click:

 - (void)buttonClicked:(id)sender {} 

Cree un gestor reconocedor (subclass), que implementará events táctiles, como touchesBegan . Puede agregarlo a la vista después de eso.

De esta manera, utilizará la composition en lugar de subsorting (que era la request).

Swift 3:

 let tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGestureRecognizer(_:))) view.addGestureRecognizer(tapGestureRecognizer) func handleTapGestureRecognizer(_ gestureRecognizer: UITapGestureRecognizer) { }