анимация кругового UIBezierPath без округления штриха

Я пытаюсь добавить анимацию к своему UIBezierPath, но я хочу сохранить резкие края, создаваемые моим текущим fillPath, вот скриншот того, как должен выглядеть результат:

введите здесь описание изображения

Мне удалось заставить одну анимацию работать правильно, используя слегка измененную версию этого кода:

// create an object that represents how the curve 

// должно быть представлено на экране

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

// add the curve to the screen
self.view.layer.addSublayer(progressLine)

// create a basic animation that animates the value 'strokeEnd'
// from 0.0 to 1.0 over 3.0 seconds
let animateStrokeEnd = CABasicAnimation(keyPath: "strokeEnd")
animateStrokeEnd.duration = 3.0
animateStrokeEnd.fromValue = 0.0
animateStrokeEnd.toValue = 1.0

// add the animation
progressLine.addAnimation(animateStrokeEnd, forKey: "animate stroke end animation")

Приведенный выше код взят из: http://mathewsanders.com/animations-in-swift-part-two/

Это сработало, но созданный им штрих был закруглен.

Единственные примеры/учебники и другие вопросы, которые я мог найти по этому вопросу, касались использования CAShapes. В настоящее время я не использую CAShapes или слои. (Я не знаю, нужно ли это, чтобы анимация работала с этим, но я бы спросил)

Вот мой текущий код (без анимации). Чтобы нарисовать мою маленькую круговую диаграмму.

class CircleChart: UIView {

var percentFill: Float = 99.00 {
    didSet {
        // Double check that it's less or equal to 100 %
        if percentFill <=  maxPercent {
            //the view needs to be refreshed
            setNeedsDisplay()
        }
    }
}

var fillColor: UIColor = UIColor.formulaBlueColor()
var chartColor: UIColor = UIColor.formulaLightGrayColor()

override func drawRect(rect: CGRect) {
    // Define the center.
    let center = CGPoint(x:bounds.width/2, y: bounds.height/2)

    // Define the radius
    let radius: CGFloat = max(bounds.width, bounds.height)

    // Define the width of the circle
    let arcWidth: CGFloat = 10

    // Define starting and ending angles (currently unused)
    let startAngle: CGFloat = degreesToRadians(-90)
    let endAngle: CGFloat = degreesToRadians(270)

    // 5
    var path = UIBezierPath(arcCenter: center,
        radius: bounds.width/2 - arcWidth/2,
        startAngle: startAngle,
        endAngle: endAngle,
        clockwise: true)

    // 6
    path.lineWidth = arcWidth
    chartColor.setStroke()
    path.stroke()

    //Draw the fill-part

    //calculate the arc for each per percent
    let arcLengthPerPercent = degreesToRadians(360/100)

    //then multiply out by the actual percent
    let fillEndAngle = arcLengthPerPercent * CGFloat(percentFill) + startAngle


    //2 - draw the outer arc
    var fillPath = UIBezierPath(arcCenter: center,
        radius: bounds.width/2 - arcWidth/2,
        startAngle: startAngle,
        endAngle: fillEndAngle,
        clockwise: true)

    //3 - draw the inner arc
    fillPath.addArcWithCenter(center,
        radius: bounds.width/2 - arcWidth/2,
        startAngle: fillEndAngle,
        endAngle: startAngle,
        clockwise: false)

    //4 - close the path
    fillPath.closePath()

    fillColor.setStroke()
    fillPath.lineWidth = arcWidth
    fillPath.stroke()
}
}

Как лучше всего анимировать fillPath? Или мне нужно переделать все в CAShapes и слоях, чтобы все заработало?

Любая помощь будет принята с благодарностью.


person Mark L    schedule 30.03.2015    source источник


Ответы (1)


Если вы хотите, чтобы он был квадратным, почему вы используете progressLine.lineCap = kCALineCapRound? Просто удалите эту строку, и вы получите торец по умолчанию (kCALineCapButt).

person rdelmar    schedule 30.03.2015
comment
работал отлично. Спасибо. Я чувствую себя таким идиотом, который портит это уже несколько часов ... Я не могу принять ответ, пока не пройдет более 8 минут. - person Mark L; 30.03.2015
comment
@MarkL, иногда просто нужен свежий взгляд. - person rdelmar; 30.03.2015