繁体   English   中英

在Swift中按下按钮时多次更新标签文本

[英]Updating Label Text several times while a Button is pressed in Swift

在我的快速项目中,我有一个按钮,当我按下按钮时,我需要完成许多工作(可以说,从按下按钮的那一刻起,这些工作大约需要40秒钟)。 因此,在这段时间里,我的按钮处于“选定”状态。 我想要的是在按下此按钮的同时多次更改标签的文本(每次在完成特定功能之后)。 所以我有这样的事情:

@IBOutlet weak var myLabel: UILabel!
@IBAction func myButton(_ sender: UIButton) {
    //Some huge functions which take 10 seconds to run
    self.myLabel.text = "Some text1"

    //Some other huge functions which take 10 seconds to run
    self.myLabel.text = "Some text2"

    //Some other other huge functions which take 10 seconds to run
    self.myLabel.text = "Some text3"

    //Some other other other huge functions which take 10 seconds to run
    self.myLabel.text = "Some text4"
}

但是,当我单击按钮时,所有这些功能开始运行并完成,但是我只看到myLabel的文本更改为“ Some text4”,之前它永远不会更改为“ Some text1”或“ Some text2”或“ Some text3”成为“ Some text4”。 我认为放置DispatchQueue.main.async {}可能会有所帮助,但仍然无法正常工作。 任何想法? 谢谢。

由于您的代码是同步的,因此该行中的代码在上一行中的代码之后立即执行。 因此,您将始终看到最后设置的文本"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)
    }
}

...您应该能够在从按下按钮的那一刻起的2、4、6秒内看到打印的Text1Text2Text3

将完成块添加到您的函数中。 然后在完成块内更改标签文本

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

}

您可以在后台队列中运行所有长时间运行的任务,并在主队列中进行标签更新。 关键是仅在第一个函数完成时才调用下一个函数,否则它们将并行运行,并且可以同时更新。 这是一个例子

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM