UIActivityIndicatorView 没有在正确的时间停止
UIActivityIndicatorView doesn't stop at the right time
我正在尝试与 UIActivityViewController
分享我应用中的视频。
所以,这个过程看起来像这样:
- 用户正在点击分享按钮。
- 我必须用我的函数
saveToShare()
为他准备视频。
- 我正在为我的 UIActivityIndicatorView 启动动画并启动
saveToShare()
。
- 我正在从
saveToShare
向我的控制器发送通知。
- 我的控制器中的 Observer 正在启动功能
shareVideo()
。
shareVideo()
看起来像这样:
func videoIsReady() {
self.activityIndicator.stopAnimating()
self.activityIndicator.isHidden = true
let videoName = "NewWatermarkedVideoNew2Share.mov"
let exportPath = NSTemporaryDirectory().appending(videoName)
let exportUrl = URL(fileURLWithPath: exportPath)
let urlData = NSData(contentsOf: exportUrl)
if ((urlData) != nil){
let videoLink = exportUrl
let objectsToShare = [videoLink]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
activityVC.popoverPresentationController?.sourceView = self.view // so that iPads won't crash
activityVC.setValue("#myhashtag", forKey: "subject")
activityVC.excludedActivityTypes = [UIActivityType.airDrop, UIActivityType.addToReadingList, UIActivityType.assignToContact, UIActivityType.copyToPasteboard, UIActivityType.openInIBooks, UIActivityType.postToTencentWeibo, UIActivityType.postToVimeo, UIActivityType.postToWeibo, UIActivityType.print, UIActivityType.saveToCameraRoll, UIActivityType.postToFlickr, UIActivityType.postToTwitter, UIActivityType(rawValue: "com.apple.reminders.RemindersEditorExtension"), UIActivityType(rawValue: "com.apple.mobilenotes.SharingExtension"),UIActivityType(rawValue: "com.google.Drive.ShareExtension"), UIActivityType(rawValue: "com.apple.mobileslideshow.StreamShareService")]
self.present(activityVC, animated: true, completion: {
})
} else {
print("url is empty...")
}
}
它有效,但我的 UIActivityIndicatorView
没有在共享对话框之前隐藏,实际上在显示该对话框后还工作了几秒钟。
这里有什么问题?
P.S。所以,如果我把 UIActivityIndicatorView
放在 DispatchQueue.main.async
中就可以了,所以我的问题就解决了,但我不知道为什么首先会出现这个问题。
您必须从后台线程调用 videoIsReady()
函数。所有 UI 调用都必须从主线程进行,否则结果是不确定的。一个常见的结果是 UI 更改需要很长时间才能出现。 (另一个常见结果是崩溃。)
要使其立即消失,您需要同步调用主队列上的代码。为了避免死锁(以防从主队列调用 videoIsReady()
),使用我开发的这个小扩展:
extension DispatchQueue {
class func safeUISync(execute workItem: DispatchWorkItem) {
if Thread.isMainThread { workItem.perform() }
else { DispatchQueue.main.sync(execute: workItem) }
}
class func safeUISync<T>(execute work: () throws -> T) rethrows -> T {
if Thread.isMainThread { return try work() }
else { return try DispatchQueue.main.sync(execute: work) }
}
}
现在您可以调用您的代码如下:
func videoIsReady() {
DispatchQueue.safeUISync {
self.activityIndicator.stopAnimating()
self.activityIndicator.isHidden = true
}
...
}
我正在尝试与 UIActivityViewController
分享我应用中的视频。
所以,这个过程看起来像这样:
- 用户正在点击分享按钮。
- 我必须用我的函数
saveToShare()
为他准备视频。 - 我正在为我的 UIActivityIndicatorView 启动动画并启动
saveToShare()
。 - 我正在从
saveToShare
向我的控制器发送通知。 - 我的控制器中的 Observer 正在启动功能
shareVideo()
。 shareVideo()
看起来像这样:func videoIsReady() { self.activityIndicator.stopAnimating() self.activityIndicator.isHidden = true let videoName = "NewWatermarkedVideoNew2Share.mov" let exportPath = NSTemporaryDirectory().appending(videoName) let exportUrl = URL(fileURLWithPath: exportPath) let urlData = NSData(contentsOf: exportUrl) if ((urlData) != nil){ let videoLink = exportUrl let objectsToShare = [videoLink] let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil) activityVC.popoverPresentationController?.sourceView = self.view // so that iPads won't crash activityVC.setValue("#myhashtag", forKey: "subject") activityVC.excludedActivityTypes = [UIActivityType.airDrop, UIActivityType.addToReadingList, UIActivityType.assignToContact, UIActivityType.copyToPasteboard, UIActivityType.openInIBooks, UIActivityType.postToTencentWeibo, UIActivityType.postToVimeo, UIActivityType.postToWeibo, UIActivityType.print, UIActivityType.saveToCameraRoll, UIActivityType.postToFlickr, UIActivityType.postToTwitter, UIActivityType(rawValue: "com.apple.reminders.RemindersEditorExtension"), UIActivityType(rawValue: "com.apple.mobilenotes.SharingExtension"),UIActivityType(rawValue: "com.google.Drive.ShareExtension"), UIActivityType(rawValue: "com.apple.mobileslideshow.StreamShareService")] self.present(activityVC, animated: true, completion: { }) } else { print("url is empty...") } }
它有效,但我的 UIActivityIndicatorView
没有在共享对话框之前隐藏,实际上在显示该对话框后还工作了几秒钟。
这里有什么问题?
P.S。所以,如果我把 UIActivityIndicatorView
放在 DispatchQueue.main.async
中就可以了,所以我的问题就解决了,但我不知道为什么首先会出现这个问题。
您必须从后台线程调用 videoIsReady()
函数。所有 UI 调用都必须从主线程进行,否则结果是不确定的。一个常见的结果是 UI 更改需要很长时间才能出现。 (另一个常见结果是崩溃。)
要使其立即消失,您需要同步调用主队列上的代码。为了避免死锁(以防从主队列调用 videoIsReady()
),使用我开发的这个小扩展:
extension DispatchQueue {
class func safeUISync(execute workItem: DispatchWorkItem) {
if Thread.isMainThread { workItem.perform() }
else { DispatchQueue.main.sync(execute: workItem) }
}
class func safeUISync<T>(execute work: () throws -> T) rethrows -> T {
if Thread.isMainThread { return try work() }
else { return try DispatchQueue.main.sync(execute: work) }
}
}
现在您可以调用您的代码如下:
func videoIsReady() {
DispatchQueue.safeUISync {
self.activityIndicator.stopAnimating()
self.activityIndicator.isHidden = true
}
...
}