ios - 如何在漫长的过程中使用事件指示器?

标签 ios swift uiactivityindicatorview

编辑2 - 好吧,我想出了一种方法来做到这一点(不确定这是否是最好的方法),但这种方法对我有用,它使用了AstroCB编写的内容和其他一些东西 - 也许我不得不这样做是因为这一切都在 UIAlert 的闭包中,并且主线程不是 reset() 或类似的东西,不确定 - 但无论如何 - 这似乎有效:

self.toggleBurgerMenu(self)
    var alert = UIAlertController(title: "Are you sure?", message: "Starting over will restore all previously discarded cards and return you to the start of 'Study Phase'!", preferredStyle: UIAlertControllerStyle.Alert)

    alert.addAction(UIAlertAction(title: "Start Over", style: UIAlertActionStyle.Destructive, handler:  { action in

        dispatch_async(dispatch_get_main_queue(), {
            NSLog("before calling reset")
            self.activityIndicator.startAnimating()
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
                reset()
                dispatch_async(dispatch_get_main_queue(), {
                    NSLog("after calling reset")
                    self.activityIndicator.stopAnimating()
                    setPlace(0, 0, "done")
                    save()
                    instructing = true
                    continuing = false

                    self.performSegueWithIdentifier("studyViewToStartSegue", sender: nil)
                })

            })

        })

    }))

[编辑 2 结束 - 感谢 AstroCB]

编辑 - 我正在尝试 AstroCB 的建议,但它不起作用,所以我想知道这是否是因为我第一次引用的一小段代码上面和/或下面的代码有关 - 所以在下一个 block 中代码是他的更改和我正在做的事情的更多上下文(显然是 UIAlertController 中的操作):

alert.addAction(UIAlertAction(title: "Start Over", style: UIAlertActionStyle.Destructive, handler:  { action in
        NSLog("before calling reset")
        self.activityIndicator.startAnimating()
        reset()
        dispatch_async(dispatch_get_main_queue(), { // Will wait until reset() has finished
            NSLog("after calling reset")
            self.activityIndicator.stopAnimating()
        })
        setPlace(0, 0, "done")
        save()
        instructing = true
        continuing = false

        self.performSegueWithIdentifier("studyViewToStartSegue", sender: nil)
    }))

...

我有一个名为“reset()”的函数,该函数可能需要几秒钟的时间,因此我想在其处理期间显示事件指示器。这是我的代码:

NSLog("before calling reset")
self.activityIndicator.startAnimating()
reset()
NSLog("after calling reset")
self.activityIndicator.stopAnimating()

我很确定我的事件指示器设置正确,因为我通过使用 start 和 stopAnimating() 放置“开”和“关”按钮来测试它,并且它与按钮配合得很好。您看到的 NSLogs 之间间隔了 3 秒的“reset()”时间 - 只是我的事件指示器从未显示。

我在 Storyboard中设置了事件指示器,并且未选中“动画”(因为如果我检查它是否从该 View Controller 的加载中显示出来并且永远不会消失 - 即使我看到的教程说要检查以启用该功能)并且我选中了“停止时隐藏”和“隐藏”。我还尝试将 .hidden = false 添加到上面的 startanimiating 中,但仍然没有显示。

最佳答案

该函数正在异步运行;您的应用程序不会停止并等待 reset() 完成,然后再继续编写代码(即使这是您实际编写代码时最直观的思考方式)。

因此,您实际上是在打开指示器动画,然后立即将其关闭。要解决这个问题,您必须告诉应用在停止动画之前等待该函数完成,您可以使用 dispatch_async 来实现:

NSLog("before calling reset")
self.activityIndicator.startAnimating()
reset()
dispatch_async(dispatch_get_main_queue(), { // Will wait until reset() has finished
    NSLog("after calling reset")
    self.activityIndicator.stopAnimating()
})

关于ios - 如何在漫长的过程中使用事件指示器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28523059/

相关文章:

ios - 无需滚动即可为 UITableViewCell 设置动画高度更改

ios - 在 CustomView 中点击手势识别器查看而不是 subview

ios - 在一个 iOS 开发者帐户中提供的应用程序能否在不同的 iTunes Connect 帐户中提交?

ios - Swift 异常堆栈中的 Dead & Exploded 是什么?

ios - 在 Swift 中使用 JSON 显示 UIActivityIndi​​catorView

iphone - UIActivityIndi​​catorView 无响应

ios - 所有实例属性的核心数据总和

ios - layer.addSublayer 与 layer.insertSublayer 动画

swift - 来自解析的数据未通过 prepareForSegue 传递

ios - 如何在 UIAlertController 中心显示事件指示器?