Comment attribuer une action à l'objet UIImageView dans Swift

186

J'essaie d'attribuer un UIImageViewà une action lorsque l'utilisateur la touche.

Je sais comment créer une action pour a UIButton, mais comment pourrais-je imiter le même comportement de a UIButton, mais en utilisant a UIImageView?

user3706773
la source

Réponses:

421

Vous aurez besoin d'un UITapGestureRecognizer. Pour configurer, utilisez ceci:

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
}

(Vous pouvez également utiliser un UIButtonet lui attribuer une image, sans texte et simplement connecter un IBAction)

Aseider
la source
3
Nitpick: var tgr = UITapGestureRecognizer (target: self action: Selector ("imageTapped:")), nécessite une virgule entre les deux paramètres.
sysuser
3
comme indiqué ci-dessous par MidHun MP, assurez-vous d'avoir le userInteractionEnabled = true
Sheraz
2
Dans Swift 3.0, la syntaxe de l'action: Selector ("imageTapped:") a été remplacée par action: #selector (imageTapped))
emily
2
Également dans Swift 3.0, la propriété userInteractionEnabled a été renommée isUserInteractionEnabled
Doug Amos
2
En utilisant Swift 4, cela a fonctionné pour moi, mais j'ai dû ajouter un @objcmodificateur à la fonction.
Mark Lyons
68

Vous devez ajouter un outil de reconnaissance de gestes (pour appuyer, utiliser UITapGestureRecognizer , pour appuyer et maintenir, utiliser UILongPressGestureRecognizer ) à votre UIImageView.

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

Et implémentez la méthode de sélection comme:

@objc func tappedMe()
{
    println("Tapped on Image")
}
Député de Midhun
la source
13
userInteractionEnabled est la clé.
kennydust
@hatim: Quel est le problème auquel vous êtes confronté? Si vous avez un nouveau problème, postez-le en tant que nouvelle question.
Midhun MP
@MidhunMP Je génère la vue d'image dynamiquement et j'ai fait exactement ce qui est écrit dans cette réponse mais la fonction tappedMe () n'est pas appelée
hatim
1
Cela a fonctionné pour moi avec les changements suivants: let tap = UITapGestureRecognizer (target: self, action: #selector (ViewController.tappedMe)) // ligne suivante -> successIndicatorImg.addGestureRecognizer (tap) // ligne suivante -> successIndicatorImg.isUserInteractionEnabled = true
Almir Campos
@hatim utilisez-vous le même geste pour plusieurs vues de l'interface utilisateur? Je viens de résoudre ce problème car j'utilisais le même geste pour plusieurs vues et qu'un seul fonctionnait pour moi. lorsque je crée plusieurs gestes, cela a fonctionné pour moi.
nadafafif
36

Vous pouvez ajouter un UITapGestureRecognizerà l'imageView, faites-en simplement glisser un dans votre Storyboard / xib, faites glisser tout en maintenant la touche Ctrl enfoncée de l'imageView vers le gestureRecognizer et en maintenant la touche Ctrl enfoncée depuis le gestureRecognizer vers le fichier Swift pour créer unIBAction .

Vous devrez également activer les interactions des utilisateurs sur le UIImageView, comme indiqué dans cette image: entrez la description de l'image ici

Emil
la source
4
UIImageViewne répond pas aux touches par défaut. Vous devez également activer les interactions des utilisateurs.
rmaddy
@rmaddy Oups, c'est vrai. Édité.
Emil
1
J'aime la façon dont vous pouvez configurer cela à l'aide de l'IB, le glisser / déposer est puissant et je ne m'attendais pas à ce que ce soit possible. +1 pour ça. En tant que noob, il serait facile de ne pas savoir comment il est connecté sans «passer la souris» sur le storyboard. Cela dépend de votre préférence, mais je préfère "le voir dans le code".
angryITguy
14

Pour swift 2.0 et supérieur, procédez comme suit

@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
la source
userInteractionEnabled a maintenant été renommé isUserInteractionEnabled
Chaim Friedman
11

Code Swift4

Essayez ces nouvelles méthodes d'extension:

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

}

Maintenant, chaque fois que nous voulons ajouter un UITapGestureRecognizerà une UIViewou une UIViewsous - classe commeUIImageView , nous pouvons le faire sans créer de fonctions associées pour les sélecteurs!

Usage:

 profile_ImageView.addTapGestureRecognizer {
        print("image tapped")
    }
Ravindra_Bhati
la source
2
Fonctionne très bien. et cela a grandement simplifié la mise en œuvre.
Nick N
me fait un peu peur avec les fonctions de réflexion utilisées - y a-t-il de bonnes chances que cela fonctionne dans les futures versions swift?
BananaAcid
1
C'est très élégant et utile. Fonctionne pour moi
Taylor Maxwell
2
❤️J'aime les extensions
Ricardo
8

Vous pouvez en fait simplement définir l'image du UIButtonà ce que vous mettriez normalement dans un fichier UIImageView. Par exemple, où vous feriez:

myImageView.image = myUIImage

Vous pouvez à la place utiliser:

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

Alors, voici à quoi pourrait ressembler votre code:

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
}

L'avantage d'utiliser cette méthode est que si vous devez charger l'image à partir d'une base de données, vous pouvez définir le titre du bouton avant de définir l'image:

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

Pour informer vos utilisateurs que vous chargez l'image

Jojodmo
la source
2

Besoin d'ajouter un paresseux pour que TapGestureRecognizer s'enregistre
puisque le 'self' dans UITapGestureRecognizer (cible: self ...) sera nul si ce n'est pas une var paresseuse. Même si vous définissez isUserInteractionEnable = true, il ne s'enregistrera pas sans 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
la source
1

Vous pouvez mettre un UIButtonavec un fond transparent sur le dessus de UIImageView, et écouter un appui sur le bouton avant de charger l'image

depsch ali
la source
1
C'est une façon rapide de décrire une option. Je pensais que tous le monde savais cela!
depsch ali
3
Ce n'est pas une bonne idée d'ajouter des composants d'interface utilisateur inutiles sans raison réelle. Cela augmentera la complexité de l'interface utilisateur et vous devrez également faire face aux mêmes contraintes de mise en page automatique. Il est simplement préférable d'ajouter un TapGestureRecognizer.
Gunhan
1

Code Swift 4


Étape 1 Dans ViewdidLoad ()

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

Étape 2 Ajouter la fonction suivante

@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

    }

Il est testé et fonctionne correctement

Sachin Rasane
la source
0

Je suggère de placer le bouton invisible (opacité = 0) sur votre imageview, puis de gérer l'interaction sur le bouton.

levan
la source