记得之前看过一个文字动画的Demo,但不记的出处啦,只知道是需要UIBezierPath的分类的,然后参考了 YYKit 中的UIBezierPath+YYAdd.m, 接着实现下面这个文字动画的,一步一步组成的文字。
I am bad man.gif
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
// Layer
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.frame = self.view.frame;
shapeLayer.geometryFlipped = YES;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.lineWidth = 2.0;
shapeLayer.lineJoin = kCALineJoinRound;
[self.view.layer addSublayer:shapeLayer];
// Path
UIBezierPath *path = [self bezierPathWithText:@"I am bad Man" attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:24]}]; //文字、大小
shapeLayer.bounds = CGPathGetBoundingBox(path.CGPath);
shapeLayer.path = path.CGPath;
shapeLayer.strokeColor = [UIColor orangeColor].CGColor; // 字体颜色
[shapeLayer removeAllAnimations];
// Animation
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnimation.duration = 3.0; // 动画时间
pathAnimation.fromValue = @(0.1);
pathAnimation.toValue = @(1.0);
// Layer Add Animaiotion
[shapeLayer addAnimation:pathAnimation forKey:@"path_animation"];
}
- (UIBezierPath *)bezierPathWithText:(NSString *)text attributes:(NSDictionary *)attrs; {
NSAssert(text!= nil && attrs != nil, @"参数不能为空");
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:text
attributes:attrs];
CGMutablePathRef paths = CGPathCreateMutable();
CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attrString);
CFArrayRef runArray = CTLineGetGlyphRuns(line);
for (CFIndex runIndex = 0; runIndex < CFArrayGetCount(runArray); runIndex++)
{
CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runArray, runIndex);
CTFontRef runFont = CFDictionaryGetValue(CTRunGetAttributes(run), kCTFontAttributeName);
for (CFIndex runGlyphIndex = 0; runGlyphIndex < CTRunGetGlyphCount(run); runGlyphIndex++)
{
CFRange thisGlyphRange = CFRangeMake(runGlyphIndex, 1);
CGGlyph glyph;
CGPoint position;
CTRunGetGlyphs(run, thisGlyphRange, &glyph);
CTRunGetPositions(run, thisGlyphRange, &position);
{
CGPathRef path = CTFontCreatePathForGlyph(runFont, glyph, NULL);
CGAffineTransform t = CGAffineTransformMakeTranslation(position.x, position.y);
CGPathAddPath(paths, &t,path);
CGPathRelease(path);
}
}
}
CFRelease(line);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointZero];
[path appendPath:[UIBezierPath bezierPathWithCGPath:paths]];
CGPathRelease(paths);
return path;
}
不知不觉涉及到了 CoreText 中的知识点,此处暂为自己做一个了解点吧,还是先 Core Animation 学习继续···
PS:刚发现一个不错的英文文章描述这个: Animating text