Respuestas:
Comprueba que userInteractionEnabled
está YES
en el 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...
}
userInteractionEnabled
todavía debe establecerse en YES / true en Xcode 8 Objective-C / Swift
Sí, se puede agregar un UIGestureRecognizer a un 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 userInteractionEnabled
propiedad en YES
. UIImageView hereda de UIView, cuya propiedad de interacción de usuario está configurada YES
de manera predeterminada, sin embargo, la propiedad de interacción de usuario de UIImageView está configurada NO
de manera predeterminada.
De los documentos 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 a UIPinchGestureRecognizer
, a UIRotationGestureRecognizer
y a UIPanGestureRecognizer
.
Primero, en viewDidLoad
u otro método de su elección, cree una vista de imagen, dele una imagen, un marco y permita su interacción con el usuario. Luego crea los tres gestos de la siguiente manera. Asegúrese de utilizar su propiedad delegada (muy probablemente configurada como self). Esto será necesario para 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 llamarán cuando se detecten los gestos en su vista. Dentro de ellos, verificaremos el estado actual del gesto, y si está en el inicio o el cambioUIGestureRecognizerState
, leeremos la propiedad de escala / rotación / traducción del gesto, aplicaremos esos datos a una transformación afín, aplicaremos la transformación afín a la imagen. ver, y luego restablecer la escala de gestos / rotación / traducción.
- (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, necesitará utilizar el método UIGestureRecognizerDelegategestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer
para permitir que los gestos funcionen al mismo tiempo. Si estos tres gestos son los únicos tres gestos que tienen esta clase asignada como su delegado, simplemente puede regresarYES
como se muestra a continuación. Sin embargo, si tiene gestos adicionales que tienen esta clase asignada como su delegado, es posible que deba agregar lógica a este método para determinar qué gesto es cuál 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 así:
@interface MyClass : MySuperClass <UIGestureRecognizerDelegate>
Si prefiere jugar con el código en un proyecto de muestra en funcionamiento, puede encontrar el proyecto de muestra que he creado que contiene este código aquí.
myImageView.isUserInteractionEnabled = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped))
tapGestureRecognizer.numberOfTapsRequired = 1
myImageView.addGestureRecognizer(tapGestureRecognizer)
y cuando se toca:
@objc func imageTapped(_ sender: UITapGestureRecognizer) {
// do something when image tapped
print("image tapped")
}
Crea un reconocedor de gestos de tocar, pellizcar o deslizar en la misma mansión. A continuación, lo guiaré a través de 4 pasos para poner en marcha su reconocedor.
4 pasos
1.) Herede de UIGestureRecognizerDelegate
agregarlo a la firma de su clase.
class ViewController: UIViewController, UIGestureRecognizerDelegate {...}
2.) Controle el arrastre de su imagen a su viewController para crear un 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 llamará cuando toque su reconocedor de gestos. (Puede excluir el = nil
si lo desea).
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)
}
Su código final debería verse 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)
}
}
Acabo de hacer esto con swift4 agregando 3 gestos juntos en una sola 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 escribe para comentar. gracias
SWIFT 3 Ejemplo
override func viewDidLoad() {
self.backgroundImageView.addGestureRecognizer(
UITapGestureRecognizer.init(target: self, action:#selector(didTapImageview(_:)))
)
self.backgroundImageView.isUserInteractionEnabled = true
}
func didTapImageview(_ sender: Any) {
// do something
}
No hay delegados de reconocimiento de gestos u otras implementaciones cuando sea necesario.
Para el amante de los bloques, puede usar ALActionBlocks para agregar acción de gestos en el 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];