Как назначить действие для объекта UIImageView в Swift


186

Я пытаюсь назначить UIImageViewдействие, когда пользователь нажимает на него.

Я знаю, как создать действие для a UIButton, но как я могу имитировать то же поведение a UIButton, но используя a UIImageView?

Ответы:


421

Вы будете нуждаться в UITapGestureRecognizer. Для настройки используйте это:

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
}

(Вы также можете использовать UIButtonи назначить изображение без текста, а затем просто подключить IBAction)


3
Nitpick: var tgr = UITapGestureRecognizer (target: self action: Selector ("imageTapped:")), нужна запятая между двумя параметрами.
sysuser

3
как указано ниже MidHun MP, убедитесь, что у вас есть userInteractionEnabled = true
Шераз

2
В Swift 3.0 синтаксис action: Selector ("imageTapped:") изменился на action: #selector (imageTapped))
Эмили

2
Также в Swift 3.0 свойство userInteractionEnabled было переименовано в isUserInteractionEnabled
Дуг Амос

2
Используя Swift 4, это работало для меня, но мне пришлось добавить @objcмодификатор в функцию.
Марк Лайонс

68

Вам необходимо добавить распознаватель жестов (для касания используйте UITapGestureRecognizer , для касания и удержания используйте UILongPressGestureRecognizer ) к вашему UIImageView.

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

И реализовать метод селектора, как:

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

13
userInteractionEnabled является ключевым.
Kennydust

@hatim: С какой проблемой вы сталкиваетесь? Если у вас есть новая проблема, пожалуйста, опубликуйте ее как новый вопрос.
депутат Midhun

@MidhunMP Я генерирую представление изображения динамически и сделал именно то, что написано в этом ответе, но функция tappedMe () не
вызывается

1
Это сработало для меня со следующими изменениями: let tap = UITapGestureRecognizer (target: self, action: #selector (ViewController.tappedMe)) // следующая строка -> successIndicatorImg.addGestureRecognizer (tap) // следующая строка -> successIndicatorImg.isUserInteractionEnable = правда
Альмир Кампос

@hatim вы используете один и тот же жест для нескольких просмотров пользовательского интерфейса? Я только что решил эту проблему, так как использовал один и тот же жест для нескольких видов, и у меня работал только один. когда я создаю несколько жестов, это работает для меня.
nadafafif

36

Вы можете добавить a UITapGestureRecognizerв imageView, просто перетащите его в Storyboard / xib, перетащите Ctrl из imageView в gestRecognizer и перетащите Ctrl из gestRecognizer в Swift-файл, чтобы создать IBAction.

Вам также необходимо включить взаимодействие с пользователем на UIImageView, как показано на этом изображении: введите описание изображения здесь


4
UIImageViewне реагирует на прикосновения по умолчанию. Вы также должны включить взаимодействие с пользователем.
rmaddy

@rmaddy Ой, это правда. Ред.
Эмиль

1
Мне нравится, как вы можете настроить это с помощью IB, перетаскивание является мощным, и я не ожидал, что это возможно. +1 за это. Будучи новичком, было бы легко не знать, как это связано, без «навязывания» раскадровки. Это зависит от ваших предпочтений, но я предпочитаю «видеть это в коде».
angryITguy

14

Для Swift 2.0 и выше сделайте это

@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 теперь переименован в isUserInteractionEnabled
Хаим Фридман,

11

Код Swift4

Попробуйте это несколько новых методов расширения:

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

}

Теперь, когда мы хотим добавить a UITapGestureRecognizerв подкласс UIViewили UIViewкак UIImageView, мы можем сделать это без создания связанных функций для селекторов!

Использование:

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

2
Прекрасно работает. и это очень сильно упростило реализацию.
Ник Н

меня немного пугает использование функций отражения - есть ли шанс, что это сработает в будущих быстрых версиях?
BananaAcid

1
Это очень элегантно и полезно. Работает для меня
Тейлор Максвелл

2
LoveЯ люблю расширения
Рикардо

8

На самом деле вы можете просто установить изображение того, UIButtonчто вы обычно вставляете в UIImageView. Например, где вы будете делать:

myImageView.image = myUIImage

Вы могли бы вместо этого использовать:

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

Итак, вот как может выглядеть ваш код:

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
}

Самое замечательное в использовании этого метода заключается в том, что если вам нужно загрузить изображение из базы данных, вы можете установить заголовок кнопки, прежде чем устанавливать изображение:

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

Чтобы сообщить своим пользователям, что вы загружаете изображение


2

Нужно добавить ленивый для регистрации TapGestureRecognizer,
так как 'self' в UITapGestureRecognizer (target: self ...) будет нулевым, если это не ленивый var. Даже если вы установите isUserInteractionEnable = true, он не будет регистрироваться без ленивых переменных.

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

Вы можете поместить UIButtonповерх экрана прозрачный фон UIImageViewи прослушать нажатие кнопки перед загрузкой изображения.


1
Это быстрый способ описания варианта. Я думал, что все это знали!
Депс Али

3
Не стоит добавлять ненужные компоненты интерфейса без какой-либо реальной причины. Это увеличит сложность пользовательского интерфейса, а также вам придется иметь дело с теми же автоматическими ограничениями макета. Просто лучше добавить TapGestureRecognizer.
Ганхан

1

Swift 4 Code


Шаг 1 В ViewdidLoad ()

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

Шаг 2 Добавьте следующую функцию

@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

    }

Это проверено и работает правильно


0

Я предлагаю разместить невидимую (непрозрачность = 0) кнопку на вашем изображении, а затем обработать взаимодействие на кнопке.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.