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

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

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

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

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

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

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

61
Didia 25 Сен 2014 в 04:07
1
Попробуйте self.view.addGestureRecognizer Я не пробовал это в Swift, но это то, что я использую в Objective C.
 – 
David L
25 Сен 2014 в 04:47
1
То, что я использую self.userInteractionEnabled, означает, что эти фрагменты кода на самом деле находятся внутри интересующего меня представления, которое я изменяю. Таким образом, self.view невозможно! Спасибо за то, что внесли свой вклад!
 – 
Didia
25 Сен 2014 в 14:24

15 ответов

Лучший ответ

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

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

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

26
Didia 13 Окт 2014 в 20:00
1
У меня сейчас такая же проблема. Что вы имеете в виду, что одно из родительских представлений было создано без предоставления фрейма? Как ты делаешь это?
 – 
guest
10 Апр 2015 в 11:04
У меня была такая же проблема. У меня было представление с подвидом UIScrollView, которое имело подвид UIImageView. Я не указывал фрейм для UIImageView, и это мешало работе кнопок. Спасибо!
 – 
allocate
22 Апр 2015 в 20:40
Кто-нибудь знает, почему это может привести к тому, что распознаватель жестов не сможет определить касание ..?
 – 
Entalpi
24 Мар 2016 в 01:17
Я не могу этого понять. Где я могу добавить этот frame: для UIImageView?
 – 
Faizan Mubasher
27 Фев 2018 в 13:54
3
Подобно проблеме отсутствия кадра, у меня просто UITapGestureRecognizer не работал, потому что высота кадра представления была слишком мала для содержимого (хотя все содержимое отображалось на дисплее нормально). Возможно, это крайний случай, но добавление этого комментария на случай, если это кому-то поможет.
 – 
Nate Cook
7 Сен 2018 в 00:51

Попробуй это

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")
}
18
Kuldeep 7 Авг 2018 в 13:16
1
Спасибо, добавление userInterActionEnabled в мой UIImageView было решением в моем случае.
 – 
Marius Waldal
17 Июл 2015 в 11:51
10
Не рекомендуется размещать его в viewDidAppear, так как в итоге вы получите массу добавленных жестов.
 – 
Injectios
1 Май 2018 в 17:57
Вы можете добавить этот код в viewDidAppear, а затем удалить распознаватели жестов в viewDidDisappear. Это решит проблему бесконечного количества распознавателей жестов, добавленных к вашему виду.
 – 
Junsu Kim
20 Окт 2021 в 11:37

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

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

14
bradkratky 2 Янв 2018 в 08:30
2
Отличное дополнение!
 – 
aaannjjaa
16 Сен 2019 в 11:05

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

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

10
mattdedek 25 Ноя 2018 в 03:21
Я делаю программные просмотры, и это помогло мне.
 – 
TWOF
28 Дек 2018 в 02:40
Замечательный ответ, спасибо, он решил мою проблему.
 – 
jason d
12 Июл 2021 в 01:38

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

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
}()
8
Kuldeep 7 Авг 2018 в 13:14
1
Ты спас мне день!
 – 
Michał Ziobro
20 Сен 2018 в 15:54

Этот код у меня работает с 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 в 13:15

У меня была такая же проблема в моем программно созданном 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 в 10:24
Я хочу, чтобы люди комментировали, когда они голосуют против. Как ни странно, это сработало для меня. См. stackoverflow.com/questions/6010186/…
 – 
Simon Pickup
12 Сен 2021 в 17:58

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 в 15:54

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

1
Jeff 27 Мар 2020 в 20:59
Спасибо, что разместили это, у меня была такая же проблема, и мне было трудно отлаживать. Это помогло мне найти правильное место!
 – 
vb11
22 Авг 2020 в 12:18

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

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

0
George 19 Май 2019 в 19:46

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

3
JalxP 19 Май 2021 в 17:03

Вот список моих открытий в 2021 году, XCode 13:

  • Убедитесь, что и ваше представление, и все его супервизоры установили ограничения ширины и высоты (это очень важно)
  • Установите isUserInteractionEnabled = true для вашего обзора
  • Нет необходимости устанавливать явный фрейм или isUserInteractionEnabled для других суперпредставлений.
2
Adam Bardon 6 Авг 2021 в 14:48

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

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

enter image description here

140
Kuldeep 7 Авг 2018 в 13:15
6
Да, вот и все - я забыл об этом с тех пор, как в последний раз создавал приложение. Похоже, что-то, что нужно автоматизировать, когда вы прикрепляете распознаватель жестов.
 – 
huygir
14 Сен 2017 в 17:18
2
Вы только что сэкономили мне 30 минут.
 – 
Chen OT
18 Янв 2018 в 17:44
4
Я не понимаю, почему взаимодействие с пользователем по умолчанию отключено.
 – 
Fox5150
17 Июл 2018 в 16:10

Скорее всего, вы добавили 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 в 12:45

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

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