如何在 UI 中显示活动指示器,同时使用文件管理器创建文件

Posted

技术标签:

【中文标题】如何在 UI 中显示活动指示器,同时使用文件管理器创建文件【英文标题】:How to show Activity Indicator in UI, while creating file Using File Manger 【发布时间】:2019-08-05 11:01:45 【问题描述】:

我正在从远程服务器下载文件(.pdf、.JPG、.PNG 等)。 “fullFileURLString”是以字符串形式提供文件路径 URL。

当用户从集合视图中单击文件名时,我需要提供将文件保存在用户自己的设备中的选项。为此,我正在使用 UIDocumentInteractionController()。我打算将此功能提供给用户。

此功能运行正常。这个过程需要一些时间来完成。我想在此过程发生时显示活动指示器。但是活动指示器没有动画或没有显示在视图中。

如何在此过程发生时显示活动指示器并在 documentInteractionController 存在时隐藏活动指示器?

我试过下面的代码

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier:"showUplodedMediaCellCollectionViewCell", for: indexPath) as! showUplodedMediaCellCollectionViewCell;
        if let bytes = Memory().deviceRemainingFreeSpaceInBytes() 
            let twoHundresMb:Int64 = 283115520
            if bytes < twoHundresMb 
                Alert.showAlertView(on: self, message: "There is not enough available storage to download.")
            
            else 
                let activityIndicatior:UIActivityIndicatorView = UIActivityIndicatorView()
                activityIndicatior.center = self.view.center
                activityIndicatior.hidesWhenStopped = true
                activityIndicatior.style = .gray
                view.addSubview(activityIndicatior)
                activityIndicatior.startAnimating()
                let mediaDetails = MediaFiles?[indexPath.row]
                if let path = mediaDetails?.folderPath 
                    if let Filename = mediaDetails?.name 
                     let fullFileURLString = "\(baseURL)"+"\(path)"+"\(Filename)"
                        if let FileUrl = URL(string: fullFileURLString) 
                            let Filedata = try? Data(contentsOf: FileUrl)
                            let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
                            let documentDirectoryPath2 = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
                            let documentDirectoryPathURL = NSURL(fileURLWithPath: documentDirectoryPath)

                            if let pathComponent = documentDirectoryPathURL.appendingPathComponent(Filename) 
                                let fileManager = FileManager.default
                                let filePath = pathComponent.path
                                if fileManager.fileExists(atPath: filePath) 
                                    print("Already Have:",Filename)
                                
                                else 
                                    print("No available",Filename)
                                    let fileManager = FileManager.default
                                    let fileManagerPath = documentDirectoryPath2.appendingPathComponent(Filename)
                                    fileManager.createFile(atPath: fileManagerPath, contents: Filedata, attributes: nil)
                                    print("path:- \(fileManagerPath)")
                                
                            

                            let destinationPath = documentDirectoryPath2.appendingPathComponent(Filename)
                            let destinationURL = URL(fileURLWithPath: destinationPath)
                            let dowanloadedMediaDocumentDirectoryPathURL = NSURL(fileURLWithPath: documentDirectoryPath)

                            if let pathComponent = dowanloadedMediaDocumentDirectoryPathURL.appendingPathComponent(Filename) 
                                let fileManager = FileManager.default
                                let filePath = pathComponent.path
                                if fileManager.fileExists(atPath: filePath) 
                                    activityIndicatior.stopAnimating()
                                    var documentInteractionController = UIDocumentInteractionController()
                                    documentInteractionController.url = destinationURL
                                    if !documentInteractionController.presentOpenInMenu(from: cell.bounds, in: view, animated: true) 
                                        print("You don't have an app installed that can handle ePub files.")

                                    
                                
                                else 
                                    Alert.showAlertView(on: self, message: "Unable to download file from remote server.")
                                
                            
                        
                    
                
             
        
        else 
            Alert.showAlertView(on: self, message: "There is not enough available storage to download.")
        
    

我希望 ActivityIndi​​cator 会保持动画,直到 documentInteractionController 不存在。

【问题讨论】:

尝试注释掉startAnimating()后面的所有代码,现在可以看到activityIndi​​cator了吗? @TalCohen 是的,如果我删除或评论 startAnimating() 下面的代码。 我建议将所有这些代码放在startAnimating() 之后的后台线程中,并在主线程中显示UIDocumentInteractionController @TalCohen 你能分享一些代码吗? 很难进入你的代码,但我会分享一些可以解释它的代码 【参考方案1】:

你应该把所有下载文件的进程放在后台线程中。

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 

    // Some code here

    DispatchQueue.main.async 
        activityIndicatior.startAnimating()
    

    DispatchQueue.global(qos: .userInitiated).async   
        // Download file or perform expensive task

        DispatchQueue.main.async 
            activityIndicator.stopAnimating()
        
    


将您的代码拆分为具有单一职责的函数,这将使您的代码更易于调试。

【讨论】:

以上是关于如何在 UI 中显示活动指示器,同时使用文件管理器创建文件的主要内容,如果未能解决你的问题,请参考以下文章

使用Blackberry JAVA SDK 6.0活动指示器UI元素加载屏幕轮

Android活动指示器?

如何隐藏和显示加载微调器 - 活动指示器反应原生,管理道具和状态

如何使用 swift 在 WKWebView 的页面中间显示活动指示器?

如何使用Swift在iOS 8上显示带有文本的活动指示器?

向核心数据添加大量数据,同时保持 UI 响应式