Cómo asignar una acción para el objeto UIImageView en Swift

186

Estoy tratando de asignar un UIImageViewa una acción cuando el usuario la toca.

Sé cómo crear una acción para a UIButton, pero ¿cómo podría imitar el mismo comportamiento de a UIButton, pero usando a UIImageView?

usuario3706773
fuente

Respuestas:

421

Necesitarás un UITapGestureRecognizer. Para configurar use esto:

override func viewDidLoad()
{
    super.viewDidLoad()

    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
    imageView.isUserInteractionEnabled = true
    imageView.addGestureRecognizer(tapGestureRecognizer)
}

@objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
{
    let tappedImage = tapGestureRecognizer.view as! UIImageView

    // Your action
}

(También puede usar UIButtonay asignarle una imagen, sin texto y simplemente conectar un IBAction)

Aseider
fuente
3
Nitpick: var tgr = UITapGestureRecognizer (target: self action: Selector ("imageTapped:")), necesita una coma entre los dos parámetros.
sysuser
3
como se indica a continuación por MidHun MP, asegúrese de tener el userInteractionEnabled = true
Sheraz
2
En Swift 3.0, la sintaxis de acción: Selector ("imageTapped:") cambió a acción: #selector (imageTapped))
Emily
2
También en Swift 3.0, la propiedad userInteractionEnabled ha cambiado de nombre a isUserInteractionEnabled
Doug Amos el
2
Usando Swift 4, esto funcionó para mí, pero tuve que agregar un @objcmodificador a la función.
Mark Lyons
68

Debe agregar un reconocedor de gestos (para tocar use UITapGestureRecognizer , para tocar y sostener use UILongPressGestureRecognizer ) a su UIImageView.

let tap = UITapGestureRecognizer(target: self, action: #selector(YourClass.tappedMe))
imageView.addGestureRecognizer(tap)
imageView.isUserInteractionEnabled = true

E implementar el método selector como:

@objc func tappedMe()
{
    println("Tapped on Image")
}
Midhun MP
fuente
13
userInteractionEnabled es la clave.
kennydust
@hatim: ¿Cuál es el problema que enfrenta? Si tiene un nuevo problema, publíquelo como una nueva pregunta.
Midhun MP
@MidhunMP Estoy generando la vista de la imagen dinámicamente y he hecho exactamente lo que está escrito en esta respuesta, pero no se llama a la función tappedMe ()
hatim
1
Me funcionó con los siguientes cambios: let tap = UITapGestureRecognizer (target: self, action: #selector (ViewController.tappedMe)) // next line -> successIndicatorImg.addGestureRecognizer (tap) // next line -> successIndicatorImg.isUserInteractionEnabled = cierto
Almir Campos
@hatim, ¿estás usando el mismo gesto para varias vistas de IU? Acabo de resolver este problema ya que estaba usando el mismo gesto para varias vistas y solo una funcionaba para mí. cuando creo múltiples gestos me funcionó.
nadafafif
36

Puede agregar un UITapGestureRecognizera imageView, simplemente arrastre uno a su Storyboard / xib, arrastre Ctrl y arrastre desde imageView al gestoReconocidor, y Ctrl-arrastre desde el gestorReconocidor al archivo Swift para crear un archivo IBAction.

También deberá habilitar las interacciones del usuario en el UIImageView, como se muestra en esta imagen: ingrese la descripción de la imagen aquí

Emil
fuente
44
UIImageViewno responde a toques por defecto. También debe habilitar las interacciones del usuario.
rmaddy
@rmaddy Vaya, eso es cierto. Editado
Emil
1
Me gusta cómo puedes configurar esto usando el IB, arrastrar / soltar es poderoso, y no esperaba que fuera posible. +1 por eso. Como novato, sería fácil no saber cómo está conectado sin "pasar el rato" por el guión gráfico. Depende de su preferencia, pero prefiero "verlo en código".
angryITguy
14

Para swift 2.0 y superior, haga esto

@IBOutlet weak var imageView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let tap = UITapGestureRecognizer(target: self, action: #selector(ViewController.tappedMe))
        imageView.addGestureRecognizer(tap)
        imageView.userInteractionEnabled = true
    }
    func tappedMe()
    {
        print("Tapped on Image")
    }
Abhishek Kumar
fuente
userInteractionEnabled ahora ha cambiado su nombre a isUserInteractionEnabled
Chaim Friedman
11

Código Swift4

Pruebe esto con algunos métodos de extensión nuevos:

import UIKit

extension UIView {

    fileprivate struct AssociatedObjectKeys {
        static var tapGestureRecognizer = "MediaViewerAssociatedObjectKey_mediaViewer"
    }

    fileprivate typealias Action = (() -> Void)?


    fileprivate var tapGestureRecognizerAction: Action? {
        set {
            if let newValue = newValue {
                // Computed properties get stored as associated objects
                objc_setAssociatedObject(self, &AssociatedObjectKeys.tapGestureRecognizer, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
            }
        }
        get {
            let tapGestureRecognizerActionInstance = objc_getAssociatedObject(self, &AssociatedObjectKeys.tapGestureRecognizer) as? Action
            return tapGestureRecognizerActionInstance
        }
    }


    public func addTapGestureRecognizer(action: (() -> Void)?) {
        self.isUserInteractionEnabled = true
        self.tapGestureRecognizerAction = action
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture))
        self.addGestureRecognizer(tapGestureRecognizer)
    }


    @objc fileprivate func handleTapGesture(sender: UITapGestureRecognizer) {
        if let action = self.tapGestureRecognizerAction {
            action?()
        } else {
            print("no action")
        }
    }

}

Ahora, cuando queramos agregar a UITapGestureRecognizera una UIViewo UIViewsubclase comoUIImageView , ¡podemos hacerlo sin crear funciones asociadas para los selectores!

Uso:

 profile_ImageView.addTapGestureRecognizer {
        print("image tapped")
    }
Ravindra_Bhati
fuente
2
Funciona genial. y simplificó mucho la implementación por mucho.
Nick N
me asusta un poco con las funciones de reflexión utilizadas: ¿hay una buena posibilidad de que esto funcione en futuras versiones rápidas?
BananaAcid
1
Esto es muy elegante y útil. Funciona para mí
Taylor Maxwell
2
❤️Me encantan las extensiones
Ricardo
8

En realidad, podría configurar la imagen de UIButtonlo que normalmente pondría en a UIImageView. Por ejemplo, donde harías:

myImageView.image = myUIImage

En su lugar, podría usar:

myButton.setImage(myUIImage, forState: UIControlState.Normal)

Entonces, así es como se vería su código:

override func viewDidLoad(){
  super.viewDidLoad()

  var myUIImage: UIImage //set the UIImage here
  myButton.setImage(myUIImage, forState: UIControlState.Normal)
}

@IBOutlet var myButton: UIButton!
@IBAction func buttonTap(sender: UIButton!){
  //handle the image tap
}

Lo mejor de usar este método es que si tiene que cargar la imagen desde una base de datos, puede configurar el título del botón antes de configurar la imagen:

myButton.setTitle("Loading Image...", forState: UIControlState.Normal)

Para decirle a sus usuarios que está cargando la imagen

Jojodmo
fuente
2

Es necesario agregar perezoso para que TapGestureRecognizer se registre,
ya que el 'self' en UITapGestureRecognizer (target: self ...) será nulo si no es un var perezoso. Incluso si establece isUserInteractionEnable = true, no se registrará sin lazy var.

lazy var imageSelector : UIImageView = {
    let image = UIImageView(image: "imageName.png")
    //now add tap gesture
    image.isUserInteractionEnabled = true
    image.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleImageSelector)))
    return image
}()
@objc private func handleImageSelector() {
    print("Pressed image selector")
}
candyline
fuente
1

Puede colocar un UIButtonfondo transparente sobre la parte superior UIImageViewy escuchar un toque en el botón antes de cargar la imagen.

depsch ali
fuente
1
Es una forma rápida de describir una opción. ¡Pensé que todos sabían eso!
depsch ali
3
No es una buena idea agregar componentes de interfaz de usuario innecesarios sin ningún motivo real. Aumentará la complejidad de la interfaz de usuario y también tendrá que lidiar con las mismas restricciones de diseño automático. Es mejor agregar un TapGestureRecognizer.
Gunhan
1

Swift 4 Code


Paso 1 en ViewdidLoad ()

   let pictureTap = UITapGestureRecognizer(target: self, action: #selector(MyInfoTableViewController.imageTapped))
       userImageView.addGestureRecognizer(pictureTap)
       userImageView.isUserInteractionEnabled = true

Paso 2 Agregar la siguiente función

@objc func imageTapped() {

        let imageView = userImageView
        let newImageView = UIImageView(image: imageView?.image)
        newImageView.frame = UIScreen.main.bounds
        newImageView.backgroundColor = UIColor.black
        newImageView.contentMode = .scaleAspectFit
        newImageView.isUserInteractionEnabled = true
        let tap = UITapGestureRecognizer(target: self, action: #selector(dismissFullscreenImage))
        newImageView.addGestureRecognizer(tap)
        self.view.addSubview(newImageView)

        self.navigationController?.isNavigationBarHidden = true
        self.tabBarController?.tabBar.isHidden = true

    }

Está probado y funciona correctamente

Sachin Rasane
fuente
0

Sugiero colocar el botón invisible (opacidad = 0) en su vista de imagen y luego manejar la interacción en el botón.

levan
fuente