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

Posted

技术标签:

【中文标题】UIActivityIndi​​catorView 不会在正确的时间停止【英文标题】:UIActivityIndicatorView doesn't stop at the right time 【发布时间】:2016-12-13 12:16:24 【问题描述】:

我正在尝试与UIActivityViewController 分享我的应用中的视频。 所以,这个过程是这样的:

    用户正在点击分享按钮。 我必须用我的函数saveToShare()为他准备视频。 我正在为我的 UIActivityIndi​​catorView 启动动画并启动 saveToShare()。 我正在从saveToShare 向我的控制器发送通知。 我的控制器中的观察者正在启动函数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 在共享对话框之前没有隐藏,实际上在显示该对话框后的几秒钟内工作。

这里有什么问题?

附:所以,如果我把UIActivityIndicatorView 放在DispatchQueue.main.async 中就可以了,这样我的问题就解决了,但我不知道为什么会首先出现这个问题。

【问题讨论】:

告诉我你从哪里开始的代码? 线程问题。 @User511 代码很简单:self.activityIndi​​cator.startAnimating() @matt 是的,我刚刚使用了 DispatchQueue.main.async 它就像一个魅力,但我不明白为什么在这种情况下我必须这样做。 【参考方案1】:

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

    ...

【讨论】:

【参考方案2】:

您必须从后台线程调用您的videoIsReady() 函数。所有 UI 调用必须从主线程进行,否则结果未定义。一个常见的结果是 UI 更改需要很长时间才能出现。 (另一个常见的结果是崩溃。)

【讨论】:

谢谢!使用 'DispatchQueue.main.async' 来更改 UI 是否足够,或者我必须使用 'DispatchQueue.global(qos: .background).async' 来进行资源消耗操作?

以上是关于UIActivityIndi​​catorView 不会在正确的时间停止的主要内容,如果未能解决你的问题,请参考以下文章

UIActivityIndi catorView未在webview中显示

UIButton里面的UIActivityIndi​​catorView

Swift UIPageViewController & UIActivityIndi​​catorView

如何在 UIAlertView 的中心添加 UIActivityIndi​​catorView?

为啥是UIActivityIndi​​catorView!展开时为零?

如何在 UICollectionViewCell 中将 UIActivityIndi​​catorView 居中?