在iOS中绘制循环进度视图

时间:2016-05-26 06:40:53

标签: ios animation core-animation

在这里从这些问题中汲取了很多:Problems animating a countdown in swift sprite kitAnimating circular progress View in Swift

然而,上面的示例(以及我在网上找到的所有其他示例)显示了设置持续时间的动画进度视图。我正在将UIImage的下载进度动画为UITableView单元格。到目前为止,这是我的代码。在我的UITableViewCell子类中,我有这个:

func drawProgress(toValue: Float) {
    let circlePath = UIBezierPath(arcCenter: CGPoint(x: self.contentView.frame.width / 2, y: self.contentView.frame.height / 2), radius: 30, startAngle: 0, endAngle: 6.28, clockwise: true)
    // create its cooresponding layer
    let circleLayer = CAShapeLayer()
    circleLayer.frame = self.contentView.bounds
    circleLayer.path = circlePath.CGPath
    circleLayer.strokeColor = UIColor.blackColor().CGColor
    circleLayer.fillColor = self.contentView.backgroundColor?.CGColor
    circleLayer.lineWidth = 1.0
    self.contentView.layer.addSublayer(circleLayer)

    // create the animation
    let pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
    pathAnimation.duration = 0.1
    pathAnimation.fromValue = NSNumber(float: 0.0)
    pathAnimation.toValue = NSNumber(float: toValue)

    // apply the animation to path
    circleLayer.addAnimation(pathAnimation, forKey: "strokeEnd")
}

我正在使用NSURLSessionDownloadDelegate来监控NSData的下载进度。在该方法中,我获得了跟踪下载%的所有必要信息。这是我的代码:

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {

  //...other code above to get the correct cell for index path, etc
  myCell.drawProgress(toValue:download.progress)
  //trackCell.progressView.progress = download.progress
 }

注释掉的行:

 //myCell.progressView.progress = download.progress

是UIProgressBar。这个UIProgressBar每次都在单元格中报告并显示正确的进度,所以我知道我有所有必要的信息,而且信息是正确的,所以这只是关于我如何实现它以使其无效。目前,当我加载tableView时,我可以看到前几个单元格快速绘制动画(比实际下载快),然后当我向下滚动tableView时,所有进度条已经满了,我不知道看到它们中的任何动画。

我知道download.progress包含跟踪下载过程的正确浮点数。如何让这个CAShapeLayer为每个单元格正确设置动画?

感谢

1 个答案:

答案 0 :(得分:0)

var progressCircle = CAShapeLayer()

// computed property - set() property observer updates circle when passed new progress value
var progress: CGFloat {
    get {
        return progressCircle.strokeEnd
    }
    set {
        if (newValue >= 1) {
            progressCircle.strokeEnd = 1
        } else if (newValue < 0) {
            progressCircle.strokeEnd = 0
        } else {
            progressCircle.strokeEnd = newValue
        }
    }
}

使用 - 设置进度圈对象

func createProgressCircle() {
    let rotationTransform = CATransform3DRotate(CATransform3DIdentity, CGFloat(-M_PI_2), 0, 0, 1.0)

    // you can either create a rect for the circle now programmatically
     //or pass in the frame of an existing storyboard object to draw within
    let rectForCircle = CGRect(origin: CGPoint(myView.origin), size: CGSize(width: myView.width, height: myView.height))
    progressCircle.path = circlePath(inRect: rectForCircle).cgPath

    progressCircle.lineWidth = 4.0
    progressCircle.fillColor = UIColor.clear.cgColor
    progressCircle.strokeColor = sitchRed.cgColor
    progressCircle.transform = rotationTransform
    circleShapeView.layer.addSublayer(progressCircle)
    circleShapeView.backgroundColor = UIColor.clear // make sure the circleView is clear so underlayer circle shape can show through
    progress = 0.0
}

要显示进度更改,请将下载的当前进度值传递到viewController中的progress属性,set()属性observer将更新圆的当前笔触位置:)