斯威夫特:如何逐步画圆圈?

时间:2015-08-03 07:21:58

标签: swift cabasicanimation cashapelayer

我建立了一个最初绘制弧的项目,这个弧是圆的1/8。
然后我在viewController上放了一个按钮,每当我点击这个按钮,它就会在它上面再画一个1/8的圆圈。
但是我遇到了一个问题:当我点击按钮时,它几乎快速绘制弧线(0.25s),而不是我之前设置的持续时间(1s)。
如何点击按钮,它的消耗时间和我之前设定的持续时间相同?

import UIKit

let π = CGFloat(M_PI)

class ViewController: UIViewController {

var i: CGFloat = 1
var maxStep: CGFloat = 8

var circleLayer: CAShapeLayer?

override func viewDidLoad() {
    super.viewDidLoad()
    let startAngle = CGFloat(0)
    let endAngle = 2*π
    let ovalRect = CGRectMake(100, 100, 100, 100)

    let ovalPath = UIBezierPath(arcCenter: CGPointMake(CGRectGetMidX(ovalRect), CGRectGetMidY(ovalRect)), radius: CGRectGetWidth(ovalRect), startAngle: startAngle, endAngle: endAngle, clockwise: true)

    let circleLayer = CAShapeLayer()
    circleLayer.path = ovalPath.CGPath
    circleLayer.strokeColor = UIColor.blueColor().CGColor
    circleLayer.fillColor = UIColor.clearColor().CGColor
    circleLayer.lineWidth = 10.0
    circleLayer.lineCap = kCALineCapRound
    self.circleLayer = circleLayer

    self.view.layer.addSublayer(self.circleLayer)

    let anim = CABasicAnimation(keyPath: "strokeEnd")
    // here i set the duration
    anim.duration = 1.0
    anim.fromValue = 0.0
    anim.toValue = self.i/self.maxStep

    self.circleLayer!.strokeStart = 0.0
    self.circleLayer!.strokeEnd = self.i/self.maxStep

    self.circleLayer!.addAnimation(anim, forKey: "arc animation")
    self.i++
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// when this action be triggered, it almost draws the arc rapidly, why?
@IBAction func buttonAnimate(sender: UIButton) {
    if self.i<=self.maxStep {
        self.circleLayer!.strokeStart = 0.0
        self.circleLayer!.strokeEnd = self.i/self.maxStep
        self.i++
    }
}
}

2 个答案:

答案 0 :(得分:2)

获取@IBAction func buttonAnimate(sender: UIButton) { if self.i<=self.maxStep { self.circleLayer!.strokeStart = 0.0 self.circleLayer!.strokeEnd = self.i/self.maxStep self.circleLayer?.animationKeys() let anim = self.circleLayer?.animationForKey("arc animation") as? CABasicAnimation if anim == nil { let anim = CABasicAnimation(keyPath: "strokeEnd") // here i set the duration anim.duration = 1 anim.fromValue = (self.i - 1)/self.maxStep anim.toValue = self.i/self.maxStep self.circleLayer!.addAnimation(anim, forKey: "arc animation") } self.i++ } } 并重置属性。请参阅以下代码:

if ($_FILES["fileToUpload"]["size"] > 5000000)

希望这有帮助!

答案 1 :(得分:1)

这是正确的解决方案:

import UIKit

import UIKit

let π = CGFloat(M_PI)

class ViewController: UIViewController {

    var i: CGFloat = 1
    var maxStep: CGFloat = 8

    var prevValue : CGFloat = 0.0

    var circleLayer: CAShapeLayer?

    override func viewDidLoad() {
        super.viewDidLoad()
        let startAngle = CGFloat(0)
        let endAngle = 2*π
        let ovalRect = CGRectMake(100, 100, 100, 100)

        let ovalPath = UIBezierPath(arcCenter: CGPointMake(CGRectGetMidX(ovalRect), CGRectGetMidY(ovalRect)), radius: CGRectGetWidth(ovalRect), startAngle: startAngle, endAngle: endAngle, clockwise: true)

        let circleLayer = CAShapeLayer()
        circleLayer.path = ovalPath.CGPath
        circleLayer.strokeColor = UIColor.blueColor().CGColor
        circleLayer.fillColor = nil //UIColor.clearColor().CGColor
        circleLayer.lineWidth = 10.0
        circleLayer.lineCap = kCALineCapRound
        self.circleLayer = circleLayer

        self.view.layer.addSublayer(self.circleLayer!)



        self.circleLayer!.strokeStart = 0.0
//Initial stroke-
        setStrokeEndForLayer(self.circleLayer!, from: 0.0,  to: self.i / self.maxStep, animated: true)

        self.i++


    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    @IBAction func buttonAnimate(sender: UIButton) {
        if self.i <= self.maxStep {

            setStrokeEndForLayer(self.circleLayer!, from: (self.i - 1 ) / self.maxStep,  to: self.i / self.maxStep, animated: true)
            self.i++
        }
    }

    func setStrokeEndForLayer(layer: CALayer,  var from:CGFloat, to: CGFloat, animated: Bool)
    {

        self.circleLayer!.strokeEnd = to

        if animated
        {

            //Check if there is any existing animation is in progress, if so override, the from value
            if let circlePresentationLayer = self.circleLayer!.presentationLayer()
            {
                from = circlePresentationLayer.strokeEnd
            }

            //Remove any on going animation
            if (self.circleLayer?.animationForKey("arc animation") as? CABasicAnimation != nil)
            {
                //Remove the current animation
                self.circleLayer!.removeAnimationForKey("arc animation")
            }


            let anim = CABasicAnimation(keyPath: "strokeEnd")
            // here i set the duration
            anim.duration = 1
            anim.fromValue = from
            anim.toValue = to


            self.circleLayer!.addAnimation(anim, forKey: "arc animation")
        }
    }

}