在我的快速项目中,我有一个按钮,当我按下按钮时,我需要完成许多工作(可以说,从按下按钮的那一刻起,这些工作大约需要40秒钟)。因此,在这段时间里,我的按钮处于“选定”状态。我想要的是在按下此按钮的同时多次更改标签的文本(每次在完成特定功能之后)。所以我有这样的东西:
// Note that EditorFor template would iterate the list item for you
@Html.EditorFor(m => m.Model.StockTransactionsDetails)
但是,当我单击按钮时,所有这些功能开始运行并完成,但是我只看到myLabel的文本更改为“ Some text4”,它将永远不会更改为“ Some text1”或“ Some text2”或“ Some text3”,然后变为“ Some text4”。我认为也许 DispatchQueue.main.async {} 会有所帮助,但仍然行不通。任何想法?谢谢。
答案 0 :(得分:2)
由于您的代码是同步的,因此该行中的代码在上一行中的代码之后立即执行。因此,您将始终看到最后设置的文本"Some text4"
要在完成某些操作后调用一些代码,我们在Swift中使用了完成处理程序
func call(_ completion: @escaping (String)->Void) {
completion("SomeText")
}
在需要完成任务的那一刻,从方法内部调用完成。然后执行完成参数中的代码
call { text in // calling method
self.myLabel.text = text // this is called after you call completion(:) from inside `call(:)`
}
所以让我们在这个演示中尝试一下
@IBAction func myButton(_ sender: UIButton) {
callAfter(2, text: "Text1") { text in
print(text)
}
callAfter(4, text: "Text2") { text in
print(text)
}
callAfter(6, text: "Text3") { text in
print(text)
}
}
func callAfter(_ duration: Double, text: String, _ completion: @escaping (String)->Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + duration) {
completion(text)
}
}
...您应该能够在按下按钮后的第二,四,六秒钟内看到Text1
,Text2
,Text3
的打印内容
答案 1 :(得分:0)
将完成块添加到您的函数中。然后在完成块内更改标签文本
typealias completionBlock = () -> Void
@IBOutlet weak var myLabel: UILabel!
@IBAction func myButton(_ sender: UIButton) {
firstFunction {
self.myLabel.text = "Some text1"
}
secondFunction {
self.myLabel.text = "Some text2"
}
thirdFuntion {
self.myLabel.text = "Some text3"
}
}
func firstFunction(_ completion: @escaping completionBlock) {
// your function body
completion()
}
func secondFunction(_ completion: @escaping completionBlock) {
// your function body
completion()
}
func thirdFuntion(_ completion: @escaping completionBlock) {
// your function body
completion()
}
答案 2 :(得分:0)
您可以在后台队列中运行所有长时间运行的任务,并在主队列中更新标签。关键是仅在第一个函数完成时才调用下一个函数,否则它们将并行运行,并且可以同时更新。这是一个例子
func doSomething1() {
// as good a way as any to simulate a long-running process
sleep(1)
DispatchQueue.main.async {
self.myLabel.text = "Some text1"
}
DispatchQueue.global(qos: .background).async {
self.doSomething2()
}
}
func doSomething2() {
sleep(1)
DispatchQueue.main.async {
self.myLabel.text = "Some text2"
}
DispatchQueue.global(qos: .background).async {
self.doSomething3()
}
}
func doSomething3() {
sleep(1)
DispatchQueue.main.async {
self.myLabel.text = "Some text3"
}
DispatchQueue.global(qos: .background).async {
self.doSomething4()
}
}
func doSomething4() {
sleep(1)
DispatchQueue.main.async {
self.myLabel.text = "Some text4"
}
}
@IBAction func cmdDoStuff(_ sender: UIButton) {
DispatchQueue.global(qos: .background).async {
self.doSomething1()
}
}