Come assegnare un'azione per l'oggetto UIImageView in Swift


186

Sto cercando di assegnare UIImageViewun'azione a quando l'utente la tocca.

So come creare un'azione per a UIButton, ma come potrei imitare lo stesso comportamento di a UIButton, ma usando a UIImageView?

Risposte:


421

Avrai bisogno di un UITapGestureRecognizer. Per impostare usa questo:

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
}

(Potresti anche usare a UIButtone assegnare un'immagine ad essa, senza testo e che semplicemente collegare un IBAction)


3
Nitpick: var tgr = UITapGestureRecognizer (target: self action: Selector ("imageTapped:")), è necessaria una virgola tra i due parametri.
sysuser,

3
come indicato di seguito da MidHun MP, assicurati di avere userInteractionEnabled = true
Sheraz,

2
In Swift 3.0 la sintassi dell'azione: Selector ("imageTapped:") è cambiata in action: #selector (imageTapped))
emily

2
Anche in Swift 3.0 la proprietà userInteractionEnabled è stata rinominata in isUserInteractionEnabled
Doug Amos,

2
Usando Swift 4, questo ha funzionato per me, ma ho dovuto aggiungere un @objcmodificatore alla funzione.
Mark Lyons,

68

Devi aggiungere un riconoscimento gesti (per toccare usa UITapGestureRecognizer , per toccare e tieni premuto usa UILongPressGestureRecognizer ) al tuo UIImageView.

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

E implementa il metodo di selezione come:

@objc func tappedMe()
{
    println("Tapped on Image")
}

13
userInteractionEnabled è la chiave.
Kennedy il

@hatim: qual è il problema che stai affrontando? Se hai un nuovo problema, pubblicalo come nuova domanda.
Midhun MP,

@MidhunMP Sto generando la visualizzazione dell'immagine in modo dinamico e ho fatto esattamente ciò che è scritto in questa risposta ma la funzione tappedMe () non viene chiamata
hatim

1
Ha funzionato per me con le seguenti modifiche: let tap = UITapGestureRecognizer (target: self, action: #selector (ViewController.tappedMe)) // next line -> successIndicatorImg.addGestureRecognizer (tap) // next line -> successIndicatorImg.isUserInteractionEnabled = true
Almir Campos,

@hatim stai usando lo stesso gesto per più viste dell'interfaccia utente? Ho appena risolto questo problema poiché stavo usando lo stesso gesto per più viste e solo uno funzionava per me. quando creo più gesti ha funzionato per me.
nadafafif,

36

Puoi aggiungere a UITapGestureRecognizera imageView, trascinarne uno nello Storyboard / xib, trascinare Ctrl dall'immagineView in gestoRecognizer e trascinare Ctrl dal gestoRecognizer nel file Swift per crearne uno IBAction.

Dovrai anche abilitare le interazioni dell'utente sul UIImageView, come mostrato in questa immagine: inserisci qui la descrizione dell'immagine


4
UIImageViewnon risponde ai tocchi per impostazione predefinita. Devi anche abilitare le interazioni dell'utente.
rmaddy,

@rmaddy Oops, è vero. Modificato.
Emil,

1
Mi piace come puoi configurarlo usando IB, il trascinamento della selezione è potente e non mi aspettavo che fosse possibile. +1 per quello. Come un noob, sarebbe facile non sapere come è collegato senza "aggirare" lo storyboard. Dipende dalle tue preferenze, ma preferisco "vederlo nel codice".
angryITguy

14

Per swift 2.0 e versioni successive, fai questo

@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 ora è stato rinominato in isUserInteractionEnabled
Chaim Friedman

11

Codice Swift4

Prova questo alcuni nuovi metodi di estensione:

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

}

Ora, ogni volta che vogliamo aggiungere un UITapGestureRecognizera UIViewo una UIViewsottoclasse come UIImageView, possiamo farlo senza creare funzioni associate per i selettori!

Uso:

 profile_ImageView.addTapGestureRecognizer {
        print("image tapped")
    }

2
Funziona alla grande. e ha semplificato di molto l'implementazione.
Nick N,

mi spaventa un po 'con le funzioni di riflessione utilizzate - ci sono buone possibilità che funzioni nelle future versioni rapide?
Banana Acid,

1
Questo è molto elegante e utile. Funziona per me
Taylor Maxwell,

2
"Adoro le estensioni
Ricardo, il

8

In realtà potresti semplicemente impostare l'immagine di UIButtonciò che normalmente inseriresti in a UIImageView. Ad esempio, dove faresti:

myImageView.image = myUIImage

Puoi invece usare:

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

Quindi, ecco come potrebbe apparire il tuo codice:

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
}

Il bello dell'utilizzo di questo metodo è che se devi caricare l'immagine da un database, puoi impostare il titolo del pulsante prima di impostare l'immagine:

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

Per dire ai tuoi utenti che stai caricando l'immagine


2

È necessario aggiungere pigro per TapGestureRecognizer per registrarsi
poiché il 'sé' in UITapGestureRecognizer (target: self ...) sarà nullo se non è un var pigro. Anche se si imposta isUserInteractionEnable = true, non verrà registrato senza var pigro.

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

È possibile inserire uno UIButtoncon uno sfondo trasparente sopra la parte superiore UIImageViewe ascoltare un tocco sul pulsante prima di caricare l'immagine


1
È un modo rapido di descrivere un'opzione. Pensavo che tutti lo sapessero!
depsch ali

3
Non è una buona idea aggiungere componenti dell'interfaccia utente non necessari senza alcun motivo reale. Aumenterà la complessità dell'interfaccia utente e dovrai anche gestire gli stessi vincoli di layout automatico. È solo meglio aggiungere un TapGestureRecognizer.
Gunhan,

1

Swift 4 Code


Passaggio 1 in ViewdidLoad ()

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

Passaggio 2: aggiungere la seguente funzione

@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

    }

È testato e funziona correttamente


0

Suggerisco di posizionare il pulsante invisibile (opacità = 0) sulla visualizzazione dell'immagine e quindi gestire l'interazione sul pulsante.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.