После инициализации подклассом UIImageView
у меня есть следующая строка кода:
self.userInteractionEnabled = true
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "handleTap:"))
Я создал необходимую ассоциированную функцию:
func handleTap(gestureRecognizer: UITapGestureRecognizer) {
print("In handler")
}
При нажатии на рассматриваемое представление «In handler никогда не выводился на консоль». Затем я удалил функцию-обработчик, чтобы посмотреть, будет ли компилятор жаловаться на отсутствующую функцию. Это не так.
Я точно в тупике. Я искренне признателен за любой свет, который люди могут пролить на это.
Обновление : мой класс на самом деле UIImageView
, а не UIView
15 ответов
Я нашел ответ после тщательного изучения своего кода.
Одно из родительских представлений было создано без предоставления frame:
Хотя это достаточно глупая ошибка, чтобы гарантировать удаление этих вопросов, есть вероятность, что у кого-то еще будет такая же проблема в будущем ...
frame:
для UIImageView?
Попробуй это
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")
}
В дополнение к другим ответам это может быть вызвано добавлением распознавателя жестов в несколько представлений. Распознаватели жестов предназначены только для отдельных просмотров.
Ссылка: https://stackoverflow.com/a/5567684/6543020
Я столкнулся с этой проблемой с программными представлениями.
Мой UIView с распознавателем жестов имел .isUserInteractionEnabled = true, но он не отвечал на касания, пока я не установил .isUserInteractionEnabled = true и для его родительских представлений.
Я нашел решение этой проблемы после многих проб и ошибок. Итак, есть два решения два:
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
}()
Этот код у меня работает с 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
}
}
У меня была такая же проблема в моем программно созданном 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)
}
}
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
}
В дополнение к вышесказанному (userInteractionEnabled
, clipsToBounds
и т. Д.), Если вы работаете с представлением в контроллере дочернего представления, убедитесь, что вы добавили его как дочерний элемент с myParentViewController.addChild(myChildViewController)
- мы столкнулись с парой ситуаций, когда видимые представления не запускали распознающие жесты, потому что их контроллеры представления не были добавлены, и предположительно сами VC не сохранялись.
Оказалось, что мой жест не сработал, потому что он был в обычном классе, а не в подклассе UIView
или чего-то еще.
Я решил проблему, создав подкласс UIView
, экземпляр которого у меня был в этом нормальном классе, и поместил в него логику жестов.
Для тех, у кого все еще есть проблемы даже со всеми предыдущими ответами, убедитесь, что вы используете UITapGestureRecognizer
вместо UIGestureRecognizer
, я все время упускал эту деталь, пытаясь найти, что было не так.
Вот список моих открытий в 2021 году, XCode 13:
- Убедитесь, что и ваше представление, и все его супервизоры установили ограничения ширины и высоты (это очень важно)
- Установите
isUserInteractionEnabled = true
для вашего обзора - Нет необходимости устанавливать явный фрейм или
isUserInteractionEnabled
для других суперпредставлений.
Я использовал UITapGestureRecognizer
, который я поместил на UILabel
с помощью раскадровки.
Чтобы это сработало, мне также пришлось поставить галочку в блоке «Взаимодействие с пользователем включено» в инспекторе атрибутов UILabel
в раскадровке.
Скорее всего, вы добавили 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")
}
}
Я решил свою проблему, установив высоту на UIView.
optionView.heightAnchor.constraint(equalToConstant: 18).isActive = true
Похожие вопросы
Связанные вопросы
Новые вопросы
ios
iOS - мобильная операционная система, работающая на Apple iPhone, iPod touch и iPad. Используйте этот тег [ios] для вопросов, связанных с программированием на платформе iOS. Используйте связанные теги [target-c] и [swift] для проблем, характерных для этих языков программирования.
self.view.addGestureRecognizer
Я не пробовал это в Swift, но это то, что я использую в Objective C.self.userInteractionEnabled
, означает, что эти фрагменты кода на самом деле находятся внутри интересующего меня представления, которое я изменяю. Таким образом,self.view
невозможно! Спасибо за то, что внесли свой вклад!