我正在尝试在创建csv文件时显示活动指示符,但它没有显示。我猜我应该以某种方式使用dispatch_async,但我无法弄清楚如何在swift 3中这样做。
var activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
override func viewDidLoad() {
super.viewDidLoad()
// activity indicator
activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 100 ,y: 200,width: 50,height: 50)) as UIActivityIndicatorView
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.gray
activityIndicator.center = self.view.center
self.view.addSubview(activityIndicator)
}
func writeToCsv() {
self.activityIndicator.startAnimating() // start the animation
let fileName = "events.csv"
let path = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(fileName)
var csvText = self.name! + "\n"
csvText += "Date,Start time,End time\n"
// create rest of comma-separated string
for event in self.events! {
let newLine = "\(event.date),\(event.startTime),\(event.endTime)\n"
csvText.append(newLine)
}
// write to csv
do {
try csvText.write(to: path!, atomically: true, encoding: String.Encoding.utf8)
} catch {
print("Failed to create file")
print(error)
}
// create and present view controller with send options
let vc = UIActivityViewController(activityItems: [path as Any], applicationActivities: [])
self.present(vc, animated: true, completion: nil)
self.activityIndicator.stopAnimating() // stop the animation
}
答案 0 :(得分:0)
错误,如果没有关于视图设置的更多上下文,很难回答这个问题。首先,确保您的活动指示器在不调用writeCsv方法的情况下可见,因此您知道您的视图层次结构是正确的。 (例如,它可能隐藏在其他一些子视图之后)
接下来,在Swift3中,Dispatch已更改为更新的API。我不确定OSX上是否使用raw libdispatch Swift wrapper,但无论如何你都可以这样访问它:
后台默认队列:
DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { /* code */ }
主要帖子:
DispatchQueue.main.async { /* Mainthread code ( UIKit stuff ) */ }
您自己的CSV生成块自定义队列:
let queue = DispatchQueue(label: "csvgenerator.queue")
queue.async { /* code */ }
现在为你的动画/ stopAnimation,确保从主线程中调用你的UIKit相关代码,以防止奇怪的glitech和/或崩溃
即:
DispatchQueue.main.async {
self.activityIndicator?.startAnimating()
}
另一个好主意可能是使用NSOperationQueue代替。它内部使用GCD我相信,但它确实很好地集成到iOS中,可能会使一些调度更容易实现。我自己总是使用GCD,但我从来没有真正需要完成的长期工作。 NSOperationQueue的一个优点是它在取消调度块方面更加用户友好。
Dave Delong撰写的WWDC应用中关于NSOperationQueue的有趣会话视频:WWDC Videos 2015
我对您的writeCSV方法做了一些小修改:
guard let path = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(fileName) else {
// Should throw an error here, or whatever is handy for your app
return
}
尽量避免在可能的所有阶段强制展开。 在具有此功能的方法中,您可以添加" throws"到函数定义的末尾,这样你就可以在没有do和catch块的情况下使用try,同时也可以在你的guard语句中抛出错误,这样无论调用writeCsv都能捕获错误并更容易将它显示给用户。