2016-12-13 13 views
1

私のアプリからのビデオをUIActivityViewControllerと共有しようとしています。 したがって、プロセスは次のようになります。UIActivityIndi​​catorViewが適切なタイミングで停止しない

  1. ユーザーが[共有]ボタンをタップしています。
  2. 私は彼のために私の機能でビデオを用意しなければなりませんsaveToShare()
  3. 私はUIActivityIndi​​catorViewのアニメーションを開始し、saveToShare()を起動しています。
  4. saveToShareから私のコントローラに通知を送信しています。
  5. 私のコントローラのオブザーバが機能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を共有ダイアログの前に隠されていませんし、実際にそのダイアログが表示された後、数秒のために働いている:

  • shareVideo()はそのように見えます。

    ここで何が間違っていますか?

    P.S.だから、もし私がDispatchQueue.main.asyncUIActivityIndicatorViewを入れれば問題は解決しますが、なぜこの問題が最初に発生したのか分かりません。

  • +0

    は私表示(場合videoIsReady()にメインキューから呼び出される)死者ロックを回避するために、私が開発したこの小さな拡張機能を使用しますあなたがそれを始める場所のコード? – User511

    +1

    スレッドの問題。 – matt

    +0

    @ User511このコードは非常にシンプルです:self.activityIndi​​cator.startAnimating() – lithium

    答えて

    0

    すぐに消えるようにするには、メインキューのコードを同期して呼び出す必要があります。次のように今、あなたはあなたのコードを呼び出すことができます

    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 
        } 
    
        ... 
    } 
    
    0

    バックグラウンドスレッドからvideoIsReady()関数を呼び出す必要があります。すべてのUI呼び出しはメインスレッドから行われなければならず、結果は未定義です。一般的な結果は、UIの変更が表示されるのにLOOONG時間かかることです。 (別の一般的な結果はクラッシュです)

    +0

    ありがとう! UIの変更に 'DispatchQueue.main.async'を使用するだけで十分ですか、リソースを消費する操作に 'DispatchQueue.global(qos:.background).async'を使用する必要がありますか? – lithium

    関連する問題