Jak przypisać akcję dla obiektu UIImageView w Swift


186

Próbuję przypisać UIImageViewakcję do akcji, gdy użytkownik ją stuknie.

Wiem, jak stworzyć akcję dla UIButton, ale jak mogę naśladować to samo zachowanie UIButton, ale używając UIImageView?

Odpowiedzi:


421

Będziesz potrzebował UITapGestureRecognizer. Aby skonfigurować, użyj tego:

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
}

(Możesz także użyć UIButtoni przypisać do niego obraz bez tekstu, a następnie po prostu podłączyć an IBAction)


3
Nitpick: var tgr = UITapGestureRecognizer (target: self action: Selector („imageTapped:”)), potrzebujesz przecinka między dwoma parametrami.
sysuser

3
jak stwierdzono poniżej przez MidHun MP, upewnij się, że masz userInteractionEnabled = true
Sheraz

2
W Swift 3.0 składnia akcji: Selector („imageTapped:”) zmieniona na action: #selector (imageTapped))
emily

2
Również w Swift 3.0 zmieniono nazwę właściwości userInteractionEnabled na isUserInteractionEnabled
Doug Amos

2
Używając Swift 4, działało to dla mnie, ale musiałem dodać @objcmodyfikator do funkcji.
Mark Lyons,

68

Musisz dodać do swojego urządzenia rozpoznawanie gestów (do korzystania z UITapGestureRecognizer , do korzystania z UILongPressGestureRecognizer ) UIImageView.

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

I zaimplementuj metodę selektora, taką jak:

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

13
userInteractionEnabled jest kluczem.
kennydust

@hatim: Z jakim problemem masz do czynienia? Jeśli masz nowy problem, opublikuj go jako nowe pytanie.
Midhun MP

@MidhunMP Generuję dynamicznie widok obrazu i zrobiłem dokładnie to, co jest napisane w tej odpowiedzi, ale funkcja tappedMe () nie jest wywoływana
hatim

1
Działa dla mnie z następującymi zmianami: let tap = UITapGestureRecognizer (target: self, action: #selector (ViewController.tappedMe)) // następny wiersz -> successIndicatorImg.addGestureRecognizer (tap) // następny wiersz -> successIndicatorImg.isUserInteractionEnabled = prawda
Almir Campos

@hatim używasz tego samego gestu do wielu widoków interfejsu użytkownika? Właśnie rozwiązałem ten problem, ponieważ używałem tego samego gestu do wielu widoków i tylko jeden działał dla mnie. kiedy tworzyłem wiele gestów, działało to dla mnie.
nadafafif

36

Możesz dodać a UITapGestureRecognizerdo imageView, po prostu przeciągnij jeden do Storyboard / xib, przeciągnij Ctrl z imageView do gestRecognizer i przeciągnij Ctrl z gestRecognizer do pliku Swift, aby utworzyć plik IBAction.

Musisz także włączyć interakcje z użytkownikiem UIImageView, jak pokazano na tym obrazku: wprowadź opis zdjęcia tutaj


4
UIImageViewdomyślnie nie reaguje na dotyk. Musisz także włączyć interakcje użytkownika.
rmaddy,

@rmaddy Ups, to prawda. Edytowane.
Emil,

1
Podoba mi się, jak możesz to skonfigurować za pomocą IB, przeciąganie / upuszczanie jest potężne i nie spodziewałem się, że to możliwe. +1 za to. Jako noob łatwo byłoby nie wiedzieć, jak to się łączy bez „kręcenia się” po scenorysie. To zależy od twoich preferencji, ale wolę „zobaczyć to w kodzie”.
złyITguy

14

W przypadku wersji 2.0 i nowszych zrób to

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

nazwa userInteractionEnabled została teraz przemianowana na isUserInteractionEnabled
Chaim Friedman

11

Kod Swift4

Wypróbuj kilka nowych metod rozszerzenia:

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

}

Teraz, gdy chcemy dodać UITapGestureRecognizerdo UIViewlub UIViewpodklasy jak UIImageViewmożemy to zrobić bez tworzenia skojarzone funkcje selektorów!

Stosowanie:

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

2
Działa świetnie. i znacznie uprościło to wdrażanie.
Nick N

nieco mnie przeraża zastosowanymi funkcjami odbicia - czy jest duża szansa, że ​​zadziała w przyszłych szybkich wersjach?
BananaAcid

1
To jest bardzo eleganckie i pomocne. Działa dla mnie
Taylor Maxwell

2
Love Uwielbiam rozszerzenia
Ricardo

8

Możesz po prostu ustawić obraz UIButtontego, co normalnie umieścisz w UIImageView. Na przykład gdzie byś zrobił:

myImageView.image = myUIImage

Zamiast tego możesz użyć:

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

Oto, jak mógłby wyglądać Twój kod:

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
}

Wspaniałą rzeczą w tej metodzie jest to, że jeśli musisz załadować obraz z bazy danych, możesz ustawić tytuł przycisku przed ustawieniem obrazu:

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

Aby poinformować użytkowników, że ładujesz obraz


2

Musisz dodać leniwy, aby TapGestureRecognizer się zarejestrował,
ponieważ „self” w UITapGestureRecognizer (target: self ...) będzie zero, jeśli nie jest to leniwy var. Nawet jeśli ustawisz isUserInteractionEnable = true, nie zarejestruje się bez leniwego 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

Możesz umieścić UIButtonprzezroczyste tło na górze UIImageViewi nasłuchiwać stuknięcia w przycisk przed załadowaniem obrazu


1
Jest to szybki sposób na opisanie opcji. Myślałem, że wszyscy to wiedzą!
depsch ali

3
Bez zbędnego powodu dodawanie niepotrzebnych elementów interfejsu użytkownika nie jest dobrym pomysłem. Zwiększy to złożoność interfejsu użytkownika, a także będziesz musiał radzić sobie z tymi samymi ograniczeniami układu automatycznego. Lepiej jest dodać TapGestureRecognizer.
Gunhan

1

Kod Swift 4


Krok 1 w ViewdidLoad ()

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

Krok 2 Dodaj następującą funkcję

@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

    }

Jest przetestowany i działa poprawnie


0

Sugeruję, aby umieścić niewidoczny przycisk (krycie = 0) na widoku obrazu, a następnie obsługiwać interakcję na przycisku.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.