iOS 动画 —— 连笔的文字

记得之前看过一个文字动画的Demo,但不记的出处啦,只知道是需要UIBezierPath的分类的,然后参考了 YYKit 中的UIBezierPath+YYAdd.m, 接着实现下面这个文字动画的,一步一步组成的文字。

iOS 动画 —— 连笔的文字_第1张图片
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

你可能感兴趣的:(iOS 动画 —— 连笔的文字)