使用rect中的draw对UIView中的属性进行动画处理

时间:2016-09-20 21:44:32

标签: swift animation

我有这样的自定义视图:

@IBDesignable
class MyTableViewCell: UITableViewCell {

@IBInspectable var cardColor : UIColor = UIColor.white
@IBInspectable var cardHorizontalPadding : Int = 20
@IBInspectable var cardVerticalPadding : Int = 20
@IBInspectable var cardCornerRadius : Int = 10
@IBInspectable var cardShadowRadius : Int = 6

var cardLayer : CAShapeLayer = CAShapeLayer()
var cardRect = CGRect.zero;

override func awakeFromNib() {
    super.awakeFromNib()

}

override func draw(_ rect: CGRect) {

    self.backgroundColor = UIColor.clear
    print("Sublayers count is \(layer.sublayers?.count)")
    let cardRect = rect.insetBy(dx: CGFloat(self.cardHorizontalPadding), dy: CGFloat(self.cardVerticalPadding))
    let cardPath = UIBezierPath(roundedRect: cardRect, cornerRadius: CGFloat(self.cardCornerRadius)).cgPath

    cardLayer.lineWidth = 0
    cardLayer.fillColor = self.cardColor.cgColor

    cardLayer.path = cardPath
    cardLayer.shadowRadius = CGFloat(self.cardShadowRadius)
    cardLayer.shadowOffset = CGSize.init(width: -0.2, height: -0.2)
    cardLayer.shadowPath = cardPath
    cardLayer.shadowOpacity = 0.2
    layer.addSublayer(cardLayer)
    layer.replaceSublayer(cardLayer, with: cardLayer)



}



override func setSelected(_ selected: Bool, animated: Bool) {


    // Configure the view for the selected state
}

}

我希望动画cardVerticalPadding,就像这样

UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1/10, animations: {

                currentCell.cardVerticalPadding = 10
            })

它无效。

1 个答案:

答案 0 :(得分:0)

来自UIView documentation

  

UIView类的以下属性是可动画的:

     
      
  •   
  • 边界
  •   
  • 中心
  •   
  • 变换
  •   
  • 阿尔法
  •   
  • 的backgroundColor
  •   

所以原因是UIKit动画框架在它可以管理的属性中非常有限。解决方案是使用CADisplayLink管理您自己的动画,以便在每次刷新显示时更新您的属性。我已经编写了一个框架来使这个变得非常容易,它可以在这里找到:https://github.com/j-h-a/Animation(使用非常宽松的MIT许可证)。也可以Cocoapods使用,只需将pod 'Animation'添加到Podfile

API与UIKit动画略有不同,而不是设置最终值,您的闭包会被重复调用,并根据progress值设置您想要的任何值传入。以下是您的案例的示例用法:

import Animation

...

Animation.animate(identifier: "animateVerticalPadding", duration: 0.1,
    update: { progress in
        currentCell.cardVerticalPadding = 20.0 <~~ progress ~~> 10.0
    })

<~~~~>运算符是我的线性插值语法,相当于lerp(20.0, 10.0, progress)20.0是初始值,10.0是最终值。如果您想使用易于缓和的曲线而不是线性曲线,那么您可以这样做:

currentCell.cardVerticalPadding = 20.0 <~~ Curve.easeInEaseOut[progress] ~~> 10.0

或者,您可以使用progress(在持续时间内从0.0增加到1.0)使用您喜欢的任何方式计算当前值,以计算您想要的当前值。插值和曲线只是帮手。