Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
415 views
in Technique[技术] by (71.8m points)

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

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()

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...