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?

użytkownik3706773
źródło

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)

Aseider
źródło
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")
}
Midhun MP
źródło
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

Emil
źródło
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")
    }
Abhishek Kumar
źródło
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")
    }
Ravindra_Bhati
źródło
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

Jojodmo
źródło
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")
}
candyline
źródło
1

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

depsch ali
źródło
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

Sachin Rasane
źródło
0

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

Levan
źródło