将点击手势添加到任何视图都不会触发

Posted

技术标签:

【中文标题】将点击手势添加到任何视图都不会触发【英文标题】:Adding Tap Gesture to any view triggers nothing 【发布时间】:2017-06-22 17:48:50 【问题描述】:

到目前为止,我正在处理 ios 开发过程中最令人沮丧的一个问题。我最初试图在我的UIImage 视图中添加一个手势识别器,但没有任何运气。我在堆栈上进行了一些搜索,发现我没有设置imageView.isUserInteractionEnabled = true,我认为这可以解决我的问题,但它没有。因此,我开始向包括imageView 的父视图在内的所有内容添加手势识别器,但仍然一无所获。我确信我正在做/没有做的事情是如此简单,但我完全错过了它。请帮忙。

ProfileViewController: UIViewController 

    // User's info container (Parent iof imageView)
let userInfoContainer: UIView = 
    let head = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    head.backgroundColor = UIColor.white
    head.translatesAutoresizingMaskIntoConstraints = false
    head.layer.borderWidth = 1
    print(head.isUserInteractionEnabled) // Returns true
    let tap = UITapGestureRecognizer(target: self, action: #selector(tapped))
    head.addGestureRecognizer(tap)
    return head
()
// Users name
let userName: UITextField = 
    let name = UITextField()
    name.text = "John Doe"
    name.translatesAutoresizingMaskIntoConstraints = false
    name.isUserInteractionEnabled  = true
    let tap = UITapGestureRecognizer(target: self, action: #selector(tapped))
    name.addGestureRecognizer(tap)
    return name
()

    // User's profile image
let profileImageView: UIImageView = 
    let imageView = UIImageView(image: #imageLiteral(resourceName: "avatar"))
    imageView.layer.cornerRadius = 50
    imageView.layer.masksToBounds = true
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.isUserInteractionEnabled = true
    imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapped)))
    return imageView
()
//
//
// skipping other UI elements
//
//
override func viewDidLoad() 
    super.viewDidLoad()
    // Authentication bits

    self.title = "Profile View"
    self.view.backgroundColor = UIColor.white
    self.view.addSubview(userInfoContainer)
    self.view.addSubview(profileImageView)
    self.view.addSubview(userName)
     // end viewDidLoad
func tapped() 
    print(123)


// setup constraints
func setupUserInfoContainer() 
    userInfoContainer.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    userInfoContainer.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    userInfoContainer.heightAnchor.constraint(equalToConstant: 200).isActive = true

// profile image arrangement
func setupProfileImage() 
    profileImageView.leftAnchor.constraint(equalTo: userInfoContainer.leftAnchor, constant: 20).isActive = true
    profileImageView.centerYAnchor.constraint(equalTo: userInfoContainer.centerYAnchor).isActive = true
    profileImageView.heightAnchor.constraint(equalToConstant: 100).isActive = true
    profileImageView.widthAnchor.constraint(equalToConstant: 100).isActive = true



func setupLabels() 
    userName.leftAnchor.constraint(equalTo: profileImageView.rightAnchor, constant: 20).isActive = true
    userName.centerYAnchor.constraint(equalTo: profileImageView.centerYAnchor).isActive = true
    userName.heightAnchor.constraint(equalToConstant: 20).isActive = true
    userName.isEnabled = false

 // end view controller

渲染视图: 查看层次结构 可能不需要的额外信息:ProfileViewController 正在由 UITabBarController 处理,但据我所见,这不应该有所作为。

更新 环顾四周,看起来合适的 swift 3 语法是 let tap = UITapGestureRecognizer(target: self, action: #selector(self.tapped(_:))) 但我认为在闭包中包含该行是导致抛出此错误的原因 ../ProfileViewController.swift:37:74: Value of type '(NSObject) -> () -> ProfileViewController' has no member 'tapped'

如果有人能解释我如何解决这个问题,那就太好了。

【问题讨论】:

您可以尝试将 tapped 的签名更改为 tapped(_ sender: Any) 并在选择器中将其更改为 tapped(_:) 吗? 我更改了签名,但仍然出现上述错误。 @ConnorG 检查viewcontoller的视图是否启用了用户交互 或者用视图调试器检查,也许有清晰背景的东西在那个视图上 self.view.isUserInteractionEnabled 返回真 @Tiko 【参考方案1】:

我不相信您可以以这种方式分配手势识别器...

1 let profileImageView: UIImageView = 
2     let imageView = UIImageView(image: #imageLiteral(resourceName: "avatar"))
3     imageView.layer.cornerRadius = 50
4     imageView.layer.masksToBounds = true
5     imageView.translatesAutoresizingMaskIntoConstraints = false
6     imageView.isUserInteractionEnabled = true
7     imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapped)))
8     return imageView
9 ()

在第 7 行,self 是什么?返回UIImageView的是函数

您的func tapped() 不属于该功能...它属于ProfileViewController

或许能找到改变目标的方法,但尝试不同方法几分钟对我来说没有任何运气。

我认为您需要在 ProfileViewController / viewDidLoad()(或该类中的其他位置)中创建和添加 GestureRecognizer。

【讨论】:

啊,所以我在上下文中引用了 UIImageView 而不是 ProfileViewController。将该行拉入 viewDidLoad 会更改对视图控制器的引用。我理解正确吗? Yes...ish :) 在您的上下文中,self 甚至不是 UIImageView...它是返回 UIImageView 的 函数。另一部分,是的……在 viewDidLoad “self”中将引用 ViewController。【参考方案2】:

问题是您没有将委托设置为点击手势。检查this

希望这会奏效

【讨论】:

那行不通。从闭包内部添加tap.delegate = self 尝试设置UIGestureRecognizerDelegate? = ProfileViewController【参考方案3】:

你为什么不在类的顶部初始化你的图像视图,比如

 let profileImageView = UIImageView()

并创建一个函数来配置图像视图并将其添加为子视图,以便在视图中加载。应该可以的

func configureImageView()  
    #add methods and customize image view
    #add image view to sub view 
 

【讨论】:

以上是关于将点击手势添加到任何视图都不会触发的主要内容,如果未能解决你的问题,请参考以下文章

使用后台代码触发时,Xamarin.forms 将变量传递给点击手势

当 UIAlertController 处于活动状态时,VoiceOver Z 手势不会触发

iOS:从顶视图到底视图拦截点击手势事件

UISwipeGestureRecognizer 没有触发

长按手势识别器触发两次[重复]

如果将点击手势识别器添加到其背景视图中,则不会调用 iOS didSelectItemAtIndexPath