是否可以以编程方式更新 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.
我目前有以下代码,我想在其中更新单击按钮后出现的标签文本。我无法根据计时器计数器更新文本,因为我相信 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.