beginTime的妙用

创建一个动画,添加到不同的图层上,可以实现复用,通过调节beginTime可以调节动画开始执行的时间。

例如,我们创建一个水平位移动画,添加到不同的图层对象上,并且让他们轮流执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let flyRight = CABasicAnimation(keyPath: "position.x")
flyRight.fromValue = 0
flyRight.toValue = 100
flyRight.duration = 0.5
flyRight.fillMode = kCAFillModeBoth

firstView.layer.addAnimation(flyRight, forKey: nil)

// make secondView perform animation on delay 0.3 seconds.
flyRight.beginTime = CACurrentMediaTime() + 0.3
secondView.layer.addAnimation(flyRight, forKey: nil)
secondView.layer.position.x = 100

// make thirdView perform animation on delay 0.4 seconds.
flyRight.beginTime = CACurrentMediaTime() + 0.4
thirdView.layer.addAnimation(flyRight, forKey: nil)
thirdView.layer.position.x = 100

动画的beginTime属性可以设置将要执行的动画的绝对开始时间,通过CACurrentMediaTime()函数获取当前时间再加上你想要延迟执行的时间的,单位秒。

动画代理

动画代理可以监听动画的进行状态,在动画开始和结束的时候回通知代理. 也就是会调用以下两个函数:

1
2
func animationDidStart(anim: CAAnimation)
func animationDidStop(anim: CAAnimation, finished flag: Bool)

CAAnimation

CAAnimation和它的子类遵循KVO,也就意味着你可以把它们当成字典一样使用来添加新的接口在运行时。

例如你可以使用这种机制来给某个动画指定一个名字,以便你能够把它和其它动画区分开。

1
flyRight.setValue("somename", forKey: "name")

CASpringAnimation

Property Default Value
damping 10.0
mass 1.0
stiffness 100.0
initialVelocity 0.0

参数说明:

  • damping - 应用给系统的阻尼
  • mass - 在系统中重物的质量
  • stiffness - 附加在重物上的弹簧的硬度
  • initialVelocity - 附加在重物上的初始速度

使用实例:

1
2
3
4
5
6
7
8
9
10
let jump = CASpringAnimation(keyPath: "position.y")
jump.initialVelocity = 100.0
jump.mass = 10.0
jump.stiffness = 1500.0
jump.damping = 50.0

jump.fromValue = textField.layer.position.y + 1.0
jump.toValue = textField.layer.position.y
jump.duration = jump.settlingDuration
textField.layer.addAnimation(jump, forKey: nil)

备注: 此动画的duration参数可以通过前面几个参数自动计算得出

jump.duration = jump.settlingDuration

使用CAGradientLayer的locations实现滑动解锁

CAGradientLayerlocations属性做动画轻松的实现iPhone自带的滑动解锁效果

a.创建一个渐变图层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
let gradientLayer: CAGradientLayer = {
    let gradientLayer = CAGradientLayer()

    // Configure the gradient here

    gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
    gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)

    let colors = [
        UIColor.blackColor().CGColor,
        UIColor.whiteColor().CGColor,
        UIColor.blackColor().CGColor
    ]
    gradientLayer.colors = colors

    let locations = [
        0.25,
        0.5,
        0.75
    ]
    gradientLayer.locations = locations

    return gradientLayer
}()

b.创建一个文本样式字典

1
2
3
4
5
6
7
8
9
let textAttributes : [String: AnyObject] = {
    let style = NSMutableParagraphStyle()
    style.alignment = .Center

    return [
        NSFontAttributeName:UIFont(name: "HelveticaNeue-Thin", size: 28.0)!,
        NSParagraphStyleAttributeName:style
    ]
}()

c.当设置文本时绘制内容,添加@IBInspectable方便看实时效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@IBInspectable var text: String! {
didSet {
    setNeedsDisplay()

    UIGraphicsBeginImageContextWithOptions(frame.size, false, 0)
    text.drawInRect(bounds, withAttributes: textAttributes)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    let maskLayer = CALayer()
    maskLayer.backgroundColor = UIColor.clearColor().CGColor
    maskLayer.frame = CGRectOffset(bounds, bounds.size.width, 0)
    maskLayer.contents = image.CGImage

    gradientLayer.mask = maskLayer
    }
}

d.重新布局gradientLayer

1
2
3
4
5
6
7
override func layoutSubviews() {
    gradientLayer.frame = CGRect(
        x: -bounds.size.width,
        y: bounds.origin.y,
        width: 3 * bounds.size.width,
        height: bounds.size.height)
}

e.添加到window时向渐变层添加动画

1
2
3
4
5
6
7
8
9
10
11
12
13
override func didMoveToWindow() {
    super.didMoveToWindow()

    layer.addSublayer(gradientLayer)

    let gradientAnimation = CABasicAnimation(keyPath: "locations")
    gradientAnimation.fromValue = [0.0, 0.0, 0.25]
    gradientAnimation.toValue = [0.75, 1.0, 1.0]
    gradientAnimation.duration = 3.0
    gradientAnimation.repeatCount = Float.infinity

    gradientLayer.addAnimation(gradientAnimation, forKey: nil)
}

Comments