UIActivityIndi​​catorView不会在正确的时间停止

时间:2016-12-13 12:16:25

标签: ios swift uiactivityindicatorview

我正在尝试使用UIActivityViewController与我的应用分享视频。 所以,过程看起来像这样:

  1. 用户点击“分享”按钮。
  2. 我必须使用我的函数saveToShare()为他准备视频。
  3. 我正在为我的UIActivityIndi​​catorView启动动画并启动saveToShare()
  4. 我正在将saveToShare的通知发送给我的控制器。
  5. 我的控制器中的观察者正在启动函数shareVideo()
  6. 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...")
    }
    
    }
    
  7. 它可以工作,但我的UIActivityIndicatorView在共享对话框之前没有被隐藏,并且在显示该对话框后实际上工作了几秒钟。

    这里有什么问题?

    P.S。所以,如果我将UIActivityIndicatorView放在DispatchQueue.main.async中,那么我的问题就解决了,但我不知道为什么会出现这个问题。

2 个答案:

答案 0 :(得分:0)

您必须从后台线程调用videoIsReady()函数。必须从主线程进行所有UI调用,或者结果未定义。常见的结果是UI更改需要花费LOOONG时间才能显示。 (另一个常见的结果是崩溃。)

答案 1 :(得分:0)

要让它立即消失,您需要同步调用主队列上的代码。为了避免死锁(如果从主队列中调用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
    }

    ...
}