如何在功能运行时更改按钮的文本

Posted

技术标签:

【中文标题】如何在功能运行时更改按钮的文本【英文标题】:How to change text of button while function is running 【发布时间】:2016-06-22 01:38:52 【问题描述】:

每当按下按钮时,我都会运行以下函数:

func deletekeyPressed(sender: UIButton!) 

    while(textDocumentProxy.hasText()) 
        (textDocumentProxy as UIKeyInput).deleteBackward()
    

    for _ in 1..<2000 
        (textDocumentProxy as UIKeyInput).deleteBackward()
    


为了防止用户认为程序正在崩溃,我希望删除按钮的文本通常显示“全部删除”到“正在删除...”,或者最好让标题在以下状态之间交替:“删除”, “正在删除。”、“正在删除……”、“正在删除……”

到目前为止,我已经尝试在函数的开头和结尾放置一个setTitle() for UIControlState.Normal,以便在函数运行时使文本显示“正在删除”。

这使我的函数看起来像这样:

    func deletekeyPressed(sender: UIButton!) 
    sender.setTitle("Deleting...", forState: .Normal)

    while(textDocumentProxy.hasText()) 
        (textDocumentProxy as UIKeyInput).deleteBackward()
    

    for _ in 1..<2000 
        (textDocumentProxy as UIKeyInput).deleteBackward()
    

    sender.setTitle("Deleting...", forState: .Normal)

但是,什么都没有发生。如何实施此解决方案?

更新一:我这样实现了 Aaron 的解决方案:

 func deletekeyPressed(sender: UIButton!) 

    NSLog("-------------------")
    NSLog("Pressing delete key")

    sender.setTitle("Deleting...", forState: .Normal)
    sender.userInteractionEnabled = false



    dispatch_async(dispatch_get_main_queue()) 
    NSLog("Starting delete function")

        while(self.textDocumentProxy.hasText()) 
            NSLog("Deleting 3 times")
            (self.textDocumentProxy as UIKeyInput).deleteBackward()
            (self.textDocumentProxy as UIKeyInput).deleteBackward()
            (self.textDocumentProxy as UIKeyInput).deleteBackward()
        

        for _ in 1..<2000 
            (self.textDocumentProxy as UIKeyInput).deleteBackward()
        

        sender.setTitle("Clear", forState: .Normal)
        sender.userInteractionEnabled = true

        NSLog("Finishing delete function")
    

但是我遇到了以下问题。该解决方案部分有效,因为按钮文本将显示“正在删除...”,直到 dispatch_async 中的代码完成运行。但问题是,一旦dispatch_async 中的代码完成运行,正在删除文本的文本字段的 UI 不会立即更新。这会导致删除按钮的文本在短时间内显示“正在删除...”(只要代码完成运行),即使 UITextfield 尚未自行更新以显示代码的更改。

这是问题的视频:

注意删除函数是如何在屏幕更新之前完成调用的。

【问题讨论】:

【参考方案1】:

问题在于 UI 仅在主运行循环完成后绘制。因此,在工作完成之前,您更改文本的命令无效。

一个简单的解决方案是将删除工作安排在主队列的末尾:

func deletekeyPressed(sender: UIButton!) 
    sender.setTitle("Deleting...", forState: .Normal)
    sender.userInteractionEnabled = false

    dispatch_async(dispatch_get_main_queue()) 
        while(textDocumentProxy.hasText()) 
            (textDocumentProxy as UIKeyInput).deleteBackward()
        

        for _ in 1..<2000 
            (textDocumentProxy as UIKeyInput).deleteBackward()
        

        sender.setTitle("Deleted!", forState: .Normal)
        sender.userInteractionEnabled = true
    

【讨论】:

快速提问,“主运行循环完成”是什么意思?这是指函数中正在执行的任何内容,因此表示 UI 在函数完成调用之前不会更新? 这也发生了一些奇怪的事情。该解决方案部分有效,因为按钮显示文本“正在删除...”,直到 dispatch_async 中的代码完成运行,但由于某种原因,UI 不会在 dispatch_async 中的代码显示文本被删除完成运行,而是有一个明显的停顿。这导致按钮显示“已删除!”在实际删除文本之前。我会在一秒钟内发布一个视频。

以上是关于如何在功能运行时更改按钮的文本的主要内容,如果未能解决你的问题,请参考以下文章

如何在运行时更改布局?

Android - 在运行时更改自定义标题视图

DOM刷新长时间运行的功能

如何在升级过程中运行捆绑包时,如何在WIX(Windows安装程序xml)引导程序项目中将按钮文本更改为“升级”?

更改片段中按钮的文本

仅当搜索栏文本不为空时,如何运行过滤器功能?