Where do you declare UITapGestureRecognizer() in relation to addGestureRecognizer() in Swift?

房东的猫 提交于 2019-12-11 15:56:30

问题


Problem

centerLabelGesture is being defined outside of the scope of viewDidLoad(), so at the time that .addGestureRecognizer(centerLabelGesture) is called, centerLabelGesture is not defined yet.

import UIKit
import SnapKit

class ViewController: UIViewController {

    var screen: UIView!
    var centerLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        screen = UIView()
        centerLabel = UILabel()

        view.addSubview(screen)
        screen.addSubview(centerLabel)

        screen.backgroundColor = .white
        screen.snp.makeConstraints { (make) in
            make.top.equalTo(view)
            make.right.equalTo(view)
            make.left.equalTo(view)
            make.bottom.equalTo(view)
        }

        centerLabel.text = "I hope I'm centered."
        centerLabel.snp.makeConstraints { (make) in
            make.center.equalTo(screen)
        }
        centerLabel.isUserInteractionEnabled = true
        centerLabel.addGestureRecognizer(centerLabelGesture)
    }

    let centerLabelGesture = UITapGestureRecognizer(target: self, action: #selector(centerLabelTapped))

    @objc func centerLabelTapped() {
        centerLabel.text = "Ouch, you tapped me!"
    }

}

Update 1/19/2019

matt pointed out that centerLabelGesture needs to be declared prior to centerLabel.addGestureRecognizer(centerLabelGesture), inside viewDidLoad()


回答1:


This is a subtle mistake. The problem is the place you've put this line:

let centerLabelGesture = UITapGestureRecognizer(target: self, action: #selector(centerLabelTapped))

Move that line into the viewDidLoad code:

centerLabel.isUserInteractionEnabled = true
let centerLabelGesture = UITapGestureRecognizer(target: self, action: #selector(centerLabelTapped))
centerLabel.addGestureRecognizer(centerLabelGesture)

The reason is that where you've got that line, it's an instance property, and when you say self as the target in an instance property initializer, it doesn't mean what you think it does (it means the class, not the instance), so the message when you tap is misdirected and does nothing.

I have filed a bug on this issue; in my opinion the compiler should at least warn you that you're making a potential mistake.




回答2:


Try adding this line in viewDidLoad

centerLabelGesture.numberOfTapsRequired = 1


来源:https://stackoverflow.com/questions/51676744/where-do-you-declare-uitapgesturerecognizer-in-relation-to-addgesturerecognize

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!