是否可以以编程方式更新 UILabel 文本,该文本在函数中更新,然后通过选择器调用?

Is it possible to programmatically update a UILabel text that is updated within a function that is then called through a selector?

我目前有以下代码,我想在其中更新单击按钮后出现的标签文本。我无法根据计时器计数器更新文本,因为我相信 UI 标签没有在主线程中更新。但是,我不确定将 DispatchQueue.main.async() 放在哪里。因为 imglabel.text 变量在 imageButtonTap 内更新,这会造成混乱,因为函数是通过 addTarget 调用的。有谁知道我如何更新文本?

var counter = 0
var timer = Timer()    
var imglabel = UILabel()
class TaskViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()

            timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(UpdateTime), userInfo: nil, repeats: true)
            var imagesall = UIImage()
            let imagesView = UIButton()
            imagesView.setImage(imagesall, for: UIControl.State.normal)
            imagesView.addTarget(self, action:#selector(TaskViewController.imageButtonTap(_:)), for: .touchUpInside)
            self.view.addSubview(imagesView)
    }

       @objc func imageButtonTap(_ sender:TaskButton!) {
            let imageView = UIImageView(image: UIImage(named: img_name))
            imageView.backgroundColor = UIColor.clear
            imageView.frame = CGRect(x: 0, y: 0, width: sender.frame.size.width, height: sender.frame.size.height)
            self.imglabel.frame = CGRect(x: 0, y: 0, width: sender.frame.size.width, height: sender.frame.size.height)
            self.imglabel.clipsToBounds = true
            self.imglabel.backgroundColor = UIColor.clear
            self.imglabel.textAlignment = .center
            self.imglabel.text = String(self.counter)

            self.imglabel.center = imageView.center
            // Puts label on top of image. 
            UIGraphicsBeginImageContextWithOptions(self.imglabel.bounds.size, false, 0)
            imageView.layer.render(in: UIGraphicsGetCurrentContext()!)
            self.imglabel.layer.render(in: UIGraphicsGetCurrentContext()!)
            let imageWithText = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            sender.setImage(imageWithText, for: UIControl.State.normal)
            }

func timerAction() {
        counter += 1
        imglabel.text = "\(counter)"
    }

您可以在操作方法中添加DispatchQueue.main.async。 创建一个 imagesView 作为实例方法,而不是在 vieDidLoad 中创建。

let imagesView = UIButton()
override func viewDidLoad() {
            super.viewDidLoad()

            timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(UpdateTime), userInfo: nil, repeats: true)
            var imagesall = UIImage()
            imagesView.setImage(imagesall, for: UIControl.State.normal)
            imagesView.addTarget(self, action:#selector(TaskViewController.imageButtonTap(_:)), for: .touchUpInside)
            self.view.addSubview(imagesView)
    }


@objc func imageButtonTap(_ sender:TaskButton!) {
    DispatchQueue.main.async {
        let imageView = UIImageView(image: UIImage(named: img_name))
        imageView.backgroundColor = UIColor.clear
        imageView.frame = CGRect(x: 0, y: 0, width: sender.frame.size.width, height: sender.frame.size.height)
        self.imglabel.frame = CGRect(x: 0, y: 0, width: sender.frame.size.width, height: sender.frame.size.height)
        self.imglabel.clipsToBounds = true
        self.imglabel.backgroundColor = UIColor.clear
        self.imglabel.textAlignment = .center
        self.imglabel.text = String(self.counter)

        self.imglabel.center = imageView.center
        // Puts label on top of image.
        UIGraphicsBeginImageContextWithOptions(self.imglabel.bounds.size, false, 0)
        imageView.layer.render(in: UIGraphicsGetCurrentContext()!)
        self.imglabel.layer.render(in: UIGraphicsGetCurrentContext()!)
        let imageWithText = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        sender.setImage(imageWithText, for: UIControl.State.normal)
    }

}

我针对你的情况编写了如下代码,希望对你有所帮助

class ViewController: UIViewController {
    var counter = 0
    var timer = Timer()
    var imglabel = UILabel()
    var button = UIButton(frame: CGRect(x: 50, y: 50, width: 150, height: 50))
    let imageView = UIImageView(image: UIImage(named: "auricular-phone-symbol-in-a-circle"))
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let imagesall = UIImage(named: "favorite-heart-button")
        button.setImage(imagesall, for: UIControl.State.normal)
        button.addTarget(self, action:#selector(self.imageButtonTap(_:)), for: .touchUpInside)
        self.view.addSubview(button)
    }

    @objc func imageButtonTap(_ sender:UIButton!) {
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
        imageView.backgroundColor = UIColor.clear
        imageView.frame = CGRect(x: 0, y: 0, width: sender.frame.size.width, height: sender.frame.size.height)
        self.imglabel.frame = CGRect(x: 0, y: 0, width: sender.frame.size.width, height: sender.frame.size.height)
        self.imglabel.clipsToBounds = true
        self.imglabel.backgroundColor = UIColor.clear
        self.imglabel.textAlignment = .center
        self.imglabel.text = String(self.counter)

        self.imglabel.center = imageView.center
    }

    @objc func timerAction() {
        self.counter += 1
        self.imglabel.text = "\(self.counter)"

        UIGraphicsBeginImageContextWithOptions(self.imglabel.bounds.size, false, 0)
        imageView.layer.render(in: UIGraphicsGetCurrentContext()!)
        self.imglabel.layer.render(in: UIGraphicsGetCurrentContext()!)
        let imageWithText = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        button.setImage(imageWithText, for: UIControl.State.normal)
    }
}

UILabel 不更新的主要内容是您使用 UIGraphicsImageContext 渲染显示文本,但在更新函数中您只需更新 lable.text,因此它不会更新文本。

如果我知道的一件事是正确的,当你点击按钮时应该放置计数计时器,bcz 当你在 viewDidLoad 中创建计时器时,如果你保持 5s 然后点击按钮,这个数字将是 5 而不是 0.