栏(创建为CALayer)高度/边界动画

时间:2018-03-27 14:17:36

标签: ios swift core-animation calayer

我创建了一个包含条形图(CALayer)的图表。他们的顶部和底部都有一个文本(CATextLayer)。现在我想向条形图添加一些动画(使它们从底部到顶部增加)。

这是我现在的代码(此方法创建条形并将其添加到主图层(mainLayer)):

 private func drawBar(xPos: CGFloat, yPos: CGFloat, color: UIColor? = .gray) {
    let initialBound = CGRect(x: xPos, y: mainLayer.frame.height - bottomSpace, width: barWidth, height: 0)
    let finalBound = CGRect(x: xPos, y: yPos, width: barWidth, height: mainLayer.frame.height - bottomSpace - yPos)
    let increaseBar = CABasicAnimation(keyPath: "bounds")
    increaseBar.fromValue = initialBound
    increaseBar.toValue = finalBound
    increaseBar.duration = 2.0

    let barLayer = CALayer()

    barLayer.frame = finalBound
    barLayer.cornerRadius = 20
    barLayer.backgroundColor = color?.cgColor
    barLayer.add(increaseBar, forKey: nil)
    mainLayer.addSublayer(barLayer)
}

以下是使用的属性:

  //Width of each bar
let barWidth: CGFloat = 40.0

//Space between each bar
let space: CGFloat = 20.0


//Space at the bottom of the bar to show the title
private let bottomSpace: CGFloat = 40.0

//Space at the top of each bar to show the value
private let topSpace: CGFloat = 40.0
以这种方式找到

xPosyPosindex只是一个Int,它在for in循环中从零增加到条目数,在这种情况下,它等于1):

      /// Starting x postion of the bar
     let xPos: CGFloat = space + CGFloat(index) * (barWidth + space)

    /// Starting y postion of the bar
    let yPos: CGFloat = translateHeightValueToYPosition(value: entry.height)

entry.height只是0.01.0之间的任意数字。以下是translateHeightValueToYPosition(value:)方法的定义:

 private func translateHeightValueToYPosition(value: Float) -> CGFloat {

    let height: CGFloat = CGFloat(value) * (mainLayer.frame.height - bottomSpace - topSpace)
    return mainLayer.frame.height - bottomSpace - height
}

现在,除了条形动画从它们的总高度中间开始之外,一切正常。我尝试更改yPos的值(手动),但没有成功。我还试图通过最初将其设置为height来设置栏0的动画效果,但又一次没有成功。

以下是动画的外观:

enter image description here

如何使条形从底部向顶部增加,而不是从它们的高度中间增加?我将不胜感激任何建议。

1 个答案:

答案 0 :(得分:1)

你的代码很好,这是图层的anchorPoint的唯一问题。默认的anchorPoint设置为CGPoint(x:0.5,y:0.5),它是中间的。所以你只需要改变它们。

为顶部:CGPoint.zero

表示底部:CGPoint(x:1,y:1)

以下是只有一次更正的正确代码:

private func drawBar(xPos: CGFloat, yPos: CGFloat, color: UIColor? = .gray) {
let initialBound = CGRect(x: xPos, y: mainLayer.frame.height - bottomSpace, width: barWidth, height: 0)
let finalBound = CGRect(x: xPos, y: yPos, width: barWidth, height: mainLayer.frame.height - bottomSpace - yPos)
let increaseBar = CABasicAnimation(keyPath: "bounds")
increaseBar.fromValue = initialBound
increaseBar.toValue = finalBound
increaseBar.duration = 2.0

let barLayer = CALayer()
// my code line
barLayer.anchorPoint = CGPoint(x: 1, y: 1)
barLayer.frame = finalBound
barLayer.cornerRadius = 20
barLayer.backgroundColor = color?.cgColor
barLayer.add(increaseBar, forKey: nil)
mainLayer.addSublayer(barLayer)

}

希望我的回答能解决您的问题。 :)