在无法访问以编程方式创建的 UILabel 时定义 #selector 方法

Defining a #selector method when it can't access a programmatically created UILabel

如果您以编程方式定义 UILabel,则必须在 viewDidLoad() 中这样做?但是,如果你要定义一个需要设置所述标签的 #selector 方法,这是不可能的,因为 @objc 选择器方法需要在 viewDidLoad() 方法的范围之外,它无法访问标签的地方。你如何解决这个问题?

class ViewController: UIViewController {
        
    var count = 4
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
                
        let label = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
        label.center = CGPoint(x: 250, y: 430)
        label.font = .systemFont(ofSize: 130)
        label.textColor = UIColor.black
        view.addSubview(label)
        
        Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: <#T##Selector#>, userInfo: <#T##Any?#>, repeats: <#T##Bool#>)
        
        
        @objc func updateLabel() { // ERROR @objc can only be used with members of classes...
            if count > 0 {
                count -= 1
                label.text = "\(count)"
            }
        }
    }
}

你的错误是你把选择器 updateLabel 放在了 viewDidLoad 里面。你应该把它放在 viewDidLoad 之外,这样它就是你的 class 的成员,而不是本地函数。

要访问 updateLabel 中的标签,只需将标签的声明移到两种方法之外。

您还应该在 updateLabel 中添加一个 timer 参数,这样您就可以在 count 达到 0 时停止计时器,而不是永远保持计时器 运行。

var label: UILabel!

override func viewDidLoad() {
    super.viewDidLoad()
    
    label = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
    label.center = CGPoint(x: 250, y: 430)
    label.font = .systemFont(ofSize: 130)
    label.textColor = UIColor.black
    view.addSubview(label)
    
    Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateLabel), userInfo: nil, repeats: true)
}

@objc func updateLabel(_ timer: Timer) {
    if count > 0 {
        count -= 1
        label.text = "\(count)"
    } else {
       timer.invalidate()
    }
}