ios - UIGestureRecognizer en UIImageView
tap gesture recognizer swift 4 (8)
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)
}
}
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?
Acabo de hacer esto con swift4 agregando 3 gestos juntos en vista única
- UIPinchGestureRecognizer : acercar y alejar la vista.
- UIRotationGestureRecognizer : Gire la vista.
- 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
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];
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 <UIGestureRecognizerDelegate>
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í.
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 ...
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...
}
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.
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")
}