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?

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)


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")
}

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í


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")
    }

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")
    }

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


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")
}

1

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


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


0

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.