После инициализации подклассом UIImageView у меня есть следующая строка кода:

self.userInteractionEnabled = true
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "handleTap:"))

Я создал необходимую ассоциированную функцию:

func handleTap(gestureRecognizer: UITapGestureRecognizer) {
    print("In handler")
}

При нажатии на рассматриваемое представление «In handler никогда не выводился на консоль». Затем я удалил функцию-обработчик, чтобы посмотреть, будет ли компилятор жаловаться на отсутствующую функцию. Это не так.

Я точно в тупике. Я искренне признателен за любой свет, который люди могут пролить на это.

Обновление : мой класс на самом деле UIImageView, а не UIView

57
Didia 25 Сен 2014 в 04:07

14 ответов

Лучший ответ

Я нашел ответ после тщательного изучения своего кода.

Одно из родительских представлений было создано без предоставления frame:

Хотя это достаточно глупая ошибка, чтобы гарантировать удаление этих вопросов, есть вероятность, что у кого-то еще будет такая же проблема в будущем ...

20
Didia 13 Окт 2014 в 16:00

Скорее всего, вы добавили UIGestureRecognizer не в то место. Вот рабочий образец с UIView из storyboard. Если вы создаете свой UIView динамически, вы должны поместить эту инициализацию в правильный конструктор.

class TestView: UIView
{
    override func awakeFromNib()
    {
        self.userInteractionEnabled = true
        self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "handleTap:"))
    }

    func handleTap(gestureRecognizer: UITapGestureRecognizer)
    {
        println("Here")
    }
}
9
Ravi Gautam 1 Июл 2015 в 09:45

Я столкнулся с этой проблемой с программными представлениями.

Мой UIView с распознавателем жестов имел .isUserInteractionEnabled = true, но он не отвечал на касания, пока я не установил .isUserInteractionEnabled = true и для его родительских представлений.

7
mattdedek 25 Ноя 2018 в 00:21

Я нашел решение этой проблемы после многих проб и ошибок. Итак, есть два решения два:

1. Добавьте GestureRecognizer в viewDidLoad () и включите userInteractionEnabled = true

2. При использовании вычисляемого свойства используйте для свойства lazy var вместо let.

lazy var profileImageView: UIImageView = {
    let iv = UIImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    iv.image = #imageLiteral(resourceName: "gameofthrones_splash")
    iv.contentMode = .scaleAspectFill
    iv.translatesAutoresizingMaskIntoConstraints = false
    iv.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSelectProfileImageView)))
    iv.isUserInteractionEnabled = true
    return iv
}()
5
Kuldeep 7 Авг 2018 в 10:14

Этот код у меня работает с XCode 7.0.1

import UIKit

class ImageView: UIImageView {

    init(frame: CGRect, sender: Bool, myImage: UIImage) {
        super.init(frame: frame)
        self.image = myImage
        initBorderStyle(sender)

        // enable user interaction on image.
        self.userInteractionEnabled = true
        let gesture = UITapGestureRecognizer(target: self, action: "previewImage:")
        addGestureRecognizer(gesture)

    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func previewImage(myGesture: UITapGestureRecognizer? = nil) {
        print("i'm clicked")
    }

    private func initBorderStyle(sender: Bool) {
        self.layer.masksToBounds = true
        self.layer.cornerRadius = 8
        self.layer.borderWidth = 0.5
        self.layer.borderColor = getBorderColor(sender)
        self.backgroundColor = getColor(sender)
    }


    func getBorderColor(sender: Bool) -> CGColor {
        var result: CGColor
        if sender {
            result = UIColor(red: 0.374, green: 0.78125, blue: 0.0234375, alpha: 0.5).CGColor
        } else {
            result = UIColor(red: 0.3125, green: 0.6015625, blue: 0.828125, alpha: 0.5).CGColor
        }
        return result
    }
}
2
Kuldeep 7 Авг 2018 в 10:15

Xcode 11.4 Swift 5.2

UserInteraction включен по умолчанию в Custom UIView

import UIKit

class YourView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }

    func commonInit() {
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapped))
        self.addGestureRecognizer(tapGesture)
    }

    @objc func tapped() {
        // do something
    }
}

Если вы хотите получать уведомление о том, что пользовательский UIView был нажат, тогда удобно использовать Notification.

Лучше всего создать это как расширение, чтобы предотвратить его строковую типизацию.

extension Notification.Name {
    static let DidTapMyView = Notification.Name("DidTapMyView")
}

В вашем пользовательском UIView при вызове нажатого function

@objc func tapped() {
    NotificationCenter.default.post(name: .DidTapMyView, object: self)
}

В вашем UIViewController, где вы хотите слушать Notification:

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(myViewWasTapped), name: .DidTapMyView, object: nil)
}

@objc func myViewWasTapped() {
    // Notified here - do something
}
2
rbaldwin 2 Май 2020 в 12:54

В дополнение к вышесказанному (userInteractionEnabled, clipsToBounds и т. Д.), Если вы работаете с представлением в контроллере дочернего представления, убедитесь, что вы добавили его как дочерний элемент с myParentViewController.addChild(myChildViewController) - мы столкнулись с парой ситуаций, когда видимые представления не запускали распознающие жесты, потому что их контроллеры представления не были добавлены, и предположительно сами VC не сохранялись.

1
Jeff 27 Мар 2020 в 17:59

Оказалось, что мой жест не сработал, потому что он был в обычном классе, а не в подклассе UIView или чего-то еще.

Я решил проблему, создав подкласс UIView, экземпляр которого у меня был в этом нормальном классе, и поместил в него логику жестов.

0
George_E 19 Май 2019 в 16:46

Я решил свою проблему, установив высоту на UIView.

optionView.heightAnchor.constraint(equalToConstant: 18).isActive = true
0
user6573749user6573749 7 Окт 2020 в 10:17

Для тех, у кого все еще есть проблемы даже со всеми предыдущими ответами, убедитесь, что вы используете UITapGestureRecognizer вместо UIGestureRecognizer, я все время упускал эту деталь, пытаясь найти, что было не так.

0
JalxP 19 Май 2021 в 14:03

У меня была такая же проблема в моем программно созданном ViewController. Ошибка была исправлена, когда я добавил в представление backgroundColor.

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = .systemBackground
        
        let tap = UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing))

        view.addGestureRecognizer(tap)

    }
}
-1
Lenny 12 Май 2021 в 07:24

Я использовал UITapGestureRecognizer, который я поместил на UILabel с помощью раскадровки.

Чтобы это сработало, мне также пришлось поставить галочку в блоке «Взаимодействие с пользователем включено» в инспекторе атрибутов UILabel в раскадровке.

enter image description here

138
Kuldeep 7 Авг 2018 в 10:15

Попробуй это

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)
    self.view.userInteractionEnabled = true
    var tapGesture = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
    self.view.addGestureRecognizer(tapGesture)
}

func handleTap(sender : UIView) {
    println("Tap Gesture recognized")
}
16
Kuldeep 7 Авг 2018 в 10:16

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

Ссылка: https://stackoverflow.com/a/5567684/6543020

12
bradkratky 2 Янв 2018 в 05:30