iOS 动画 —— 连笔的文字

记得之前看过一个文字动画的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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 有存有取,不要拒绝别人帮助,也要主动去帮助别人,警惕无意识取款行为
    隔壁小志龙阅读 207评论 2 2
  • 1 一直很喜欢一句话——女本柔弱,为母则刚,因为用在我母亲身上真的特别合适。 我的妈妈也曾经是一个柔弱的少女,特别...
    姬磊阅读 389评论 0 0
  • 时间如小白驹过隙,真的是飞快飞快的。一转眼,一年又过去了。 当我和老公忙着贴窗花时,望着窗外,想起了那年过年老妈老...
    代加贝贝阅读 743评论 23 6