这是什么?
此文将讲解通过形状图层
CAShaperLayer
的strokeStart
和strokeEnd
来实现动画绘制路径CGPath
,此文是By Ole Begemann创建于 December 18, 2010,当时是发布 iOS SDK 4.2 时CAShapeLayer
新增加的两个属性strokeStart和strokeEnd,这两个值是两个浮点数取值范围 0.0~1.0,用来表明形状图层所指向的路径在绘制开始和结束路径中的相对位置。
strokeStart
默认值是0.0, strokeEnd
默认值是1.0,显然这会导致形状图层的路径将一整个被绘制。假如,你想说,如果设置了layer.strokeEnd = 0.5f,只让她绘制前半部分,那该多好。
真正有趣的事情是这些接口都是可动画的。通过动画绘制 strokeEnd
从 0.0 到 1.0 在几秒内,我们就能很容易自己绘制路径像下面这样写:
1 | CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; |
最后,再添加第二个图层包含一个铅笔图片,使用关键帧动画 CAKeyframeAnimation
来让它随着这个路径以相同的速度绘制,就可以达到完美的错觉效果:
1 | CAKeyframeAnimation *penAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; |
这个对文本一样有效;我们只需要把字符转化成 CGPath
。 Core Text
提供了那样的功能的函数,CTFontCreatePathForGlyph( )。为了使用它,我们需要创建一个带属性的字符串用我们想要渲染的文本,先把它们分割成行在分割成一个个字符。在把所有的字符转换成路径后,我们以子路径方式把它添加到一个单个的 CGPath
路径中。更多细节可以查看Ohmu写的Low-level text rendering这篇文章。结果看以来非常的炫酷:
从 Github 上获得iPad 版的样品工程
你将学到的知识点
- 使用
CAShapeLayer
的strokeStart
和strokeEnd
来实现路径动画,比较高级复杂的效果像 google 的下拉刷新转圈就可以从这里引申去实现。 CABasicAnimation
和CABasicAnimation
使用- 深入理解
CAShapeLayer
和CALayer
* 通过文本创建路径,核心函数CTFontCreatePathForGlyph()
补充说明
1 | CAShapeLayer *pathLayer = [CAShapeLayer layer]; |
有一点非常重要,CALayer 在 iOS 系统中相对坐标系是以屏幕左上 top-left
为坐标原点的,在 Mac OS X 上以坐下 bottom-left
为坐标原点,但是可以通过 CALayer
的接口 geometryFlipped
垂直翻转坐标系,这个值默认是 NO
,设置成 YES
就可以把坐标系转换成左下 bottom-left
了,这里作者使用的左下 bottom-left
的坐标系。
1 | @property(getter=isGeometryFlipped) BOOL geometryFlipped; |
关于这个属性使用时需要特别注意
- 翻转会同时作用于它的子图层
- 即使这个属性设置成
YES
,图片的orientation
仍然是不变的(也就是说当设置flipped=YES
和flipped=NO
时一个CGImageRef
储存在contents
接口中的内容将会显示一致,赋值并不会真正变换底层的图层)
pathLayer 动画实现原理
- 先创建一个动画用的图层
animationLayer
类型CALayer
,用来充当动画的画布。 - 创建真正的路径图层
pathLayer
类型为CAShapeLayer
,让它的坐标系垂直翻转,并且让图层宽高同时向内收缩 100 个点,通过CGRectInset(CGRect rect, CGFloat dx, CGFloat dy)
实现 - 把
pathLayer
添加到animationLayer
的子图层中去 - 创建一个铅笔图层
penLayer
类型为CALayer
,把它添加到pathLayer
去 - 对
pathLayer
添加CABasicAnimation
动画,动画属性为strokeEnd
6. 对penLayer
添加CAKeyframeAnimation
动画,动画属性为position
#### textLayer 动画实现原理 - 先创建一个动画用的图层
animationLayer
类型CALayer
,用来充当动画的画布 - Create path from text,See:http://www.codeproject.com/KB/iPhone/Glyph.aspx,最终保存到一个类型为
CGMutablePathRef
的 letter 中 - 通过 letter 来创建文字
UIBezierPath
类型的path
4. 通过 path 再创建CAShapeLayer
pathLayer,并且把 pathLayer 添加到animationLayer
中去 - 创建一个铅笔图层
penLayer
类型为CALayer
,把它添加到pathLayer
去 - 对
pathLayer
添加CABasicAnimation
动画,动画属性为strokeEnd
6. 对penLayer
添加CAKeyframeAnimation
动画,动画属性为position
修复一处 bug
重复点击 UISegmentedControl
导致铅笔消失,这是设置了 penAnimation.delegate = self;
在代理方法里面没有判断结束直接将设置 self.penLayer.hidden = YES
,导致连续切换时铅笔不见了,要修复这个 bug 只需加一个判断if (flag) self.penLayer.hidden = YES;
即可,这样的意思是只有当动画完成时才设置 self.penLayer.hidden
的值,好了现在已经非常完美了,快去动手自己试试吧!🍺
备注:欢迎转载,但请一定注明出处! http://blog.wangruofeng007.com