代码之家  ›  专栏  ›  技术社区  ›  Mario Burga

如何删除ProgressBar循环中的cashapelayer

  •  2
  • Mario Burga  · 技术社区  · 6 年前

    我有以下代码,我正在实现这些代码以下载带有进度循环的PDF。

    它对我有效,首先我检查文件是否已保存在“documents”目录中,如果它是真的,我只显示PDF,如果PDF文件尚未加载,则 begindownloadfile().

    lass viewcontroller:uiviewcontroller,urlessiondownloadDelegate{
    @IBoutlet弱var pdfview:pdfview!
    
    设urlsting=“https://d0.awssstatic.com/whitepapers/kms-cryptographic-details.pdf”
    
    让shapelayer=cashapelayer())
    
    Let PercentageLabel:uiLabel={
    让label=uilabel())
    label.text=“说明”
    label.textAlignment=居中
    label.FONT=uiFONT.boldSystemFONT(OFSIZE:16)
    退货标签
    }()
    
    重写func viewdidload()。{
    super.viewdidload()。
    
    View.AddSubView(百分比标签)
    percentageLabel.frame=cDirect(x:0,y:0,width:100,height:100)
    percentageLabel.center=视图.center
    
    //开始画圆
    
    Let Center=视图.中心
    
    //创建跟踪层,它将填充的条下的较软颜色
    让tracklayer=cashapelayer()。
    设circularPath=uiBezierPath(arcCenter:.0,radius:100,startAngle:0,endangle:2*cgfloat.pi,顺时针:真)
    
    tracklayer.path=电路路径.cgpath
    tracklayer.strokecolor=uicolor.lightgray.cgcolor
    tracklayer.linewidth=10//条的宽度
    tracklayer.fillcolor=uicolor.clear.cgcolor//amek中间区域有清晰的颜色
    tracklayer.linecap=kcalinecapround//这使酒吧有圆角
    tracklayer.position=中心
    tracklayer.opacity=1
    视图.layer.addSublayer(tracklayer)
    
    //让circularPath=uibezierPath(arcCenter:center,radius:100,start angle:-cgfloat.pi/2,endangle:2*cgfloat.pi,顺时针:true)//这样的开始角度使条在12点钟开始
    shapelayer.path=电路路径.cgpath
    shapelayer.strokeColor=uicolor.red.cgcolor
    shapelayer.linewidth=10//条形的宽度
    shapelayer.fillcolor=uicolor.clear.cgcolor//amek中间区域有清晰的颜色
    shapelayer.linecap=kcalinecapround//这使酒吧有圆角
    shapelayer.strokeend=0
    shapelayer.position=中心
    
    shapelayer.transform=cattransform3dmakerrotation(-cgfloat.pi/2,0,0,1)
    
    视图.layer.addSublayer(shapelayer)
    
    view.addgesturerecognizer(uitapgesturerecognizer(target:self,action:selector(handletap)))
    
    
    让myurl=url(string:urlString)
    
    //然后创建文档文件夹URL
    让documentsdirectoryurl=filemanager.default.urls(用于:.documentdirectory,位于:.userDomainMask)首先!
    
    //让我们创建目标文件URL
    让destinationurl=documentsDirectoryurl.appendingPathComponent((myurl?.lastpathcomponent)!)
    打印(目标URL)
    
    
    如果fileManager.default.fileexists(atpath:destinationurl.path){
    print(“文件已存在于路径”)
    
    //隐藏标签并删除子图层(圆形)
    //self.percentagelabel.ishidden=真
    //shapelayer.removeFromSuperlayer()。
    //tracklayer.removeFromSuperlayer()。
    
    tracklayer.removeFromSuperlayer()。
    
    /***********显示PDF*****/
    让pdfrl=destinationurl.path
    让rutafile=url(fileurlwithpath:pdfull)
    打印(pdfrl)
    如果let document=pdfdocument(url:rutafile){
    self.pdfview.autoscales=真
    self.pdfview.document=文档
    }
    /***********显示PDF*****/
    
    
    }其他{
    
    开始下载文件()
    
    
    }
    
    
    
    
    }//结束didload
    
    
    
    //UrlsessionDownloadDelegate委托的Require函数
    func url session(会话:urlsession,下载任务:urlsession下载任务,didfishingsdownloadingto location:url){
    打印(“完成下载文件”)
    
    }
    
    //来自委托UrlsessionDownloadDelegate的可选func
    func urlsession(Session:urlsession,downloadtask:urlsession downloadtask,didwriteddata bytes written:int64,totalbytes written:int64,totalbytes expectedtowrite:int64){
    //打印(totalbyteswritten,totalbytesexpectedtowrite)
    设百分比=cgfloat(totalbyteswritten)/cgfloat(totalbytesexpectedtowritten)
    打印(“百分比:”,百分比)
    
    //这需要在主线程中,因为URL会话下载不在主线程上,因此如果没有DispatchQueue.main,则UI不会更新
    DispatchQueue.main.asyncqueue(调度队列.main.asyncqueue){
    self.percentagelabel.text=“(int(percentage*100))%”
    self.shapelayer.strokeend=百分比
    }
    
    }
    
    private func begindDownloadFile()。{
    
    //这样可以修复来回移动的杆
    shapelayer.strokeend=0
    
    让configuration=urlsessionconfiguration.default
    让operationQueue=operationQueue()。
    让urlsession=urlsession(配置:配置,委托:自,委托队列:操作队列)
    
    guard let url=url(string:urlString)else返回
    let downloadtask=urlsession.downloadtask(with:url)
    
    
    
    ******
    
    //然后创建文档文件夹URL
    让documentsdirectoryurl=filemanager.default.urls(用于:.documentdirectory,位于:.userDomainMask)首先!
    
    //让我们创建目标文件URL
    let destinationurl=documentsDirectoryurl.appendingPathComponent(url.lastPathComponent)
    打印(目标URL)
    
    
    //可以使用nsurlsession.sharedsession异步下载数据
    urlsession.shared.downloadtask(具有:url,completionhandler:(位置,响应,错误)->在中无效
    
    
    
    guard let location=location,error=nil else返回
    做{
    //下载文件后,需要将其移动到目标URL
    尝试filemanager.default.moveitem(位于:location,收件人:destinationurl)
    打印(“文件移动到文档文件夹”)
    打印(“文件已下载”)
    
    
    
    
    DispatchQueue.main.asyncqueue(调度队列.main.asyncqueue){
    
    //escondemos标签y removemos子层(circulo)
    
    self.percentageLabel.ishidden=真
    //self.shapelayer.removeFromSuperlayer()。
    //self.tracklayer.removeFromSuperlayer()。
    
    //self.shapelayer.removeAllanimations()。
    self.shapelayer.opacity=0
    
    
    
    /***********显示PDF*****/
    让pdfrl=destinationurl.path
    让rutafile=url(fileurlwithpath:pdfull)
    打印(pdfrl)
    如果let document=pdfdocument(url:rutafile){
    self.pdfview.autoscales=真
    self.pdfview.document=文档
    }
    
    /***********显示PDF*****/
    
    
    }
    
    
    }catch let错误为nserrror{
    打印(错误。本地化描述)
    }
    
    
    
    
    
    })继续()。
    
    
    
    /**/
    
    
    
    下载任务。继续()
    
    
    
    
    
    }
    
    fileprivate func animatecircle()。{
    让basicanization=cabasicanization(keypath:“strokeend”)//为shapelayer.strokeend设置动画
    basicanization.toValue=1
    
    基础化。持续时间=2
    
    
    //需要这两条线使钢筋在最后一点停止,否则完工后将被移除。
    basicanization.fillmode=kcaFillModeForwards
    basicanization.isremovedOnCompletion=false
    
    
    shapelayer.add(基本化,forkey:“customstring”)
    
    
    }
    
    @objc private func handletap()。{
    打印(“在此设置动画”)
    
    //开始下载文件()
    
    //animateCircle()//forkey值的自定义字符串,不确定以后在哪里使用它
    
    }
    
    
    
    
    
    
    }
    

    我的问题是我无法隐藏圆圈,我尝试了在DispatchQueue.main.asyncwithself.shapelayer.removeFromSuperlayer()and it does not work for me,either withself.shapelayer.opacity=0

    我非常感谢您的任何建议

    .begindDownloadFile ()

    lass ViewController: UIViewController, URLSessionDownloadDelegate {
        @IBOutlet weak var pdfView: PDFView!
    
        let urlString = "https://d0.awsstatic.com/whitepapers/KMS-Cryptographic-Details.pdf"
    
        let shapeLayer = CAShapeLayer()
    
        let percentageLabel: UILabel = {
            let label = UILabel()
            label.text = "Descargar"
            label.textAlignment = .center
            label.font = UIFont.boldSystemFont(ofSize: 16)
            return label
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.addSubview(percentageLabel)
            percentageLabel.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
            percentageLabel.center = view.center
    
            //start drawing circle
    
            let center  = view.center
    
            //create the track layer, the softer color underneath the bar that it is going to fill
            let trackLayer = CAShapeLayer()
            let circularPath = UIBezierPath(arcCenter: .zero, radius: 100, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)
    
            trackLayer.path = circularPath.cgPath
            trackLayer.strokeColor = UIColor.lightGray.cgColor
            trackLayer.lineWidth = 10 //the width of the bar
            trackLayer.fillColor = UIColor.clear.cgColor //amek the middle area have clear color
            trackLayer.lineCap = kCALineCapRound //this to make the bar has rounded corner
            trackLayer.position = center
            trackLayer.opacity = 1
            view.layer.addSublayer(trackLayer)
    
    //        let circularPath = UIBezierPath(arcCenter: center, radius: 100, startAngle: -CGFloat.pi / 2, endAngle: 2 * CGFloat.pi, clockwise: true) //start angle like this to have the bar start at 12 o'clock
            shapeLayer.path = circularPath.cgPath
            shapeLayer.strokeColor = UIColor.red.cgColor
            shapeLayer.lineWidth = 10 //the width of the bar
            shapeLayer.fillColor = UIColor.clear.cgColor //amek the middle area have clear color
            shapeLayer.lineCap = kCALineCapRound //this to make the bar has rounded corner
            shapeLayer.strokeEnd = 0
            shapeLayer.position = center
    
            shapeLayer.transform = CATransform3DMakeRotation(-CGFloat.pi / 2, 0, 0, 1)
    
            view.layer.addSublayer(shapeLayer)
    
            view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
    
    
          let myUrl = URL(string: urlString)
    
            // then lets create your document folder url
            let documentsDirectoryURL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    
            // lets create your destination file url
            let destinationUrl = documentsDirectoryURL.appendingPathComponent((myUrl?.lastPathComponent)!)
            print(destinationUrl)
    
    
            if FileManager.default.fileExists(atPath: destinationUrl.path) {
                print("The file already exists at path")
    
                // hidden label and remove sublayers (circle)
                //self.percentageLabel.isHidden = true
                //shapeLayer.removeFromSuperlayer()
                //trackLayer.removeFromSuperlayer()
    
                trackLayer.removeFromSuperlayer()
    
                /************** show pdf ****************/
                let pdfUrl = destinationUrl.path
                let rutafile = URL(fileURLWithPath: pdfUrl)
                print(pdfUrl)
                if let document = PDFDocument(url: rutafile) {
                    self.pdfView.autoScales = true
                    self.pdfView.document = document
                }
                /************** show pdf ****************/
    
    
            } else{
    
                 begindDownloadFile()
    
    
                }
    
    
    
    
        } // end DidLoad
    
    
    
        //the require func for URLSessionDownloadDelegate delegate
        func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
            print("finish downloading file")
    
        }
    
        //optional func from the delegate URLSessionDownloadDelegate
        func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
    //        print(totalBytesWritten, totalBytesExpectedToWrite)
            let percentage = CGFloat(totalBytesWritten) / CGFloat(totalBytesExpectedToWrite)
            print("percentage : ", percentage)
    
            //this need to be in the main thread because the url session downloading is not on the main thread, so if without DispatchQueue.main, then the UI wont update
            DispatchQueue.main.async {
                self.percentageLabel.text = "\(Int(percentage * 100))%"
                self.shapeLayer.strokeEnd = percentage
            }
    
        }
    
        private func begindDownloadFile(){
    
            //this fix the bar going back and forth
            shapeLayer.strokeEnd = 0
    
            let configuration = URLSessionConfiguration.default
            let operationQueue = OperationQueue()
            let urlSession = URLSession(configuration: configuration, delegate: self, delegateQueue: operationQueue)
    
            guard let url = URL(string: urlString) else { return }
            let downloadTask = urlSession.downloadTask(with: url)
    
    
    
            /****/
    
            // then lets create your document folder url
            let documentsDirectoryURL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    
            // lets create your destination file url
            let destinationUrl = documentsDirectoryURL.appendingPathComponent(url.lastPathComponent)
            print(destinationUrl)
    
    
            // you can use NSURLSession.sharedSession to download the data asynchronously
            URLSession.shared.downloadTask(with: url, completionHandler: { (location, response, error) -> Void in
    
    
    
                guard let location = location, error == nil else { return }
                do {
                    // after downloading your file you need to move it to your destination url
                    try FileManager.default.moveItem(at: location, to: destinationUrl)
                    print("File moved to documents folder")
                    print("file has already been downloaded")
    
    
    
    
                    DispatchQueue.main.async {
    
                        // escondemos label y removemos sublayers (circulo)
    
                        self.percentageLabel.isHidden = true
                        //self.shapeLayer.removeFromSuperlayer()
                        //self.trackLayer.removeFromSuperlayer()
    
                        //self.shapeLayer.removeAllAnimations()
                        self.shapeLayer.opacity = 0
    
    
    
                        /************** show pdf ****************/
                        let pdfUrl = destinationUrl.path
                        let rutafile = URL(fileURLWithPath: pdfUrl)
                        print(pdfUrl)
                        if let document = PDFDocument(url: rutafile) {
                            self.pdfView.autoScales = true
                            self.pdfView.document = document
                        }
    
                        /************** show pdf ****************/
    
    
                    }
    
    
                } catch let error as NSError {
                    print(error.localizedDescription)
                }
    
    
    
    
    
            }).resume()
    
    
    
            /***/
    
    
    
          downloadTask.resume()
    
    
    
    
    
        }
    
        fileprivate func animateCircle() {
            let basicAnimation = CABasicAnimation(keyPath: "strokeEnd") //animate the shapeLayer.strokeEnd
            basicAnimation.toValue = 1
    
            basicAnimation.duration = 2
    
    
            //need these 2 lines to make the bar stopped at the final point, if not it will be removed upon completion
            basicAnimation.fillMode = kCAFillModeForwards
            basicAnimation.isRemovedOnCompletion = false
    
    
            shapeLayer.add(basicAnimation,forKey: "customString")
    
    
        }
    
        @objc private func handleTap(){
            print("animate here")
    
            //begindDownloadFile()
    
    //        animateCircle()//custom string for forKey value, not sure where will use it later
    
        }
    
    
    
    
    
    
    }
    

    我的问题是我不能隐藏这个圆圈,我已经在里面试过了DispatchQueue.main.async具有self.shapeLayer.removeFromSuperlayer ()它对我也不起作用self.shapeLayer.opacity = 0

    我很感谢你的建议

    1 回复  |  直到 6 年前
        1
  •  2
  •   Travis Acton    6 年前

    let urlString = "https://d0.awsstatic.com/whitepapers/KMS-Cryptographic-Details.pdf"
    
    let shapeLayer = CAShapeLayer()
    let trackLayer = CAShapeLayer()