iOS-汉字顺序展示

前言:

主要用到以下内容: 
1.CABasicAnimation -- animationWithKeyPath:@"strokeEnd"//开始绘制
2.CAKeyframeAnimation -- animationWithKeyPath:@"position"//以position作为关键帧动画
3.CAShapeLayer//CAShapeLayer需要与贝塞尔曲线配合使用才有意义、可作为进度条
4.CALayer//展示view的layer

Demo地址


效果展示:

这里写图片描述

获取字体路径:

    UIBezierPath *path = [self getStringLayer:@"I'm Quinn-魁"];

 
 
  • 1
  • 2

通过字体路径创建CAShapeLayer:

    [path addLineToPoint:CGPointMake(0, 50)];


    CAShapeLayer *pathLayer = [CAShapeLayer layer];
    pathLayer.frame = self.view.layer.bounds;
    pathLayer.bounds = CGPathGetBoundingBox(path.CGPath);
    pathLayer.backgroundColor = [[UIColor yellowColor] CGColor];
    pathLayer.geometryFlipped = YES;
    pathLayer.path = path.CGPath;
    pathLayer.strokeColor = [UIColor colorWithRed:234.0/255 green:84.0/255 blue:87.0/255 alpha:1].CGColor;
    pathLayer.fillColor = [UIColor whiteColor].CGColor;
    pathLayer.lineWidth = 1.0f;
    pathLayer.lineJoin = kCALineJoinMiter;

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

添加到显示的view的layer上:

[self.view.layer addSublayer:pathLayer];
 
 
  • 1

再来一个图片的layer(用作关键帧动画图片):

    UIImage *penImage = [UIImage imageNamed:@"Quinn.png"];
    CALayer *penLayer = [CALayer layer];
    penLayer.contents = (id)penImage.CGImage;
    penLayer.anchorPoint = CGPointZero;
    penLayer.frame = CGRectMake(0.0f, 50.0f, penImage.size.width, penImage.size.height);
    [pathLayer addSublayer:penLayer];
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

添加到显示的view的layer上:

[self.view.layer addSublayer:penLayer];

 
 
  • 1
  • 2

当我们得到路径时,这时候还没有任何效果,只是在屏幕上绘制了一张图片和几个文字,我们需要让他动起来:

设置绘制动画

duration表示动画时间
fromValue起始状态(0-1)
toValue结束状态(0-1)
addAnimation添加路径动画
speed 速度
timeOffset 时间
速度和时间这两个属性与duration和fromValue、toValue有关
    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.duration = 10.0;
    pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
    pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
    [self.pathLayer addAnimation:pathAnimation forKey:@"strokeStart"];
    pathAnimation.speed = 0.1;
    pathAnimation.timeOffset = 0;
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

当将 strokeEnd 更改为 strokeStart

//此时动画展现方式为擦除动画,大家可以一试究竟
 
 
  • 1

这里写图片描述

让图片跟随路径动画一起动起来:

calculationMode:可以理解为动画的频率、效果
kCAAnimationLinear(线性)
kCAAnimationPaced(均匀)
kCAAnimationCubic(圆滑)
kCAAnimationCubicPaced(均匀圆滑)

delegate :
//- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag;
    CAKeyframeAnimation *penAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    penAnimation.duration = 10.0;
    penAnimation.path = self.pathLayer.path;
    penAnimation.calculationMode = kCAAnimationPaced;
    penAnimation.delegate = self;
    [self.penLayer addAnimation:penAnimation forKey:@"position"];
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

获取路径的方法:getStringLayer 方法如下:

- (UIBezierPath *)getStringLayer:(NSString *)str{
    //创建可变path  
    CGMutablePathRef letters = CGPathCreateMutable();

//    HelveticaNeue-UltraLight
//设置字体
    CTFontRef font = CTFontCreateWithName(CFSTR("Helvetica-Bold"), 32.0f, NULL);
    NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:
                           (__bridge id)font, kCTFontAttributeName,
                           nil];
    NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:str
                                                                     attributes:attrs];
    //根据字符串创建 line                                                                
    CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attrString);
    //获取每一个字符作为数组
    CFArrayRef runArray = CTLineGetGlyphRuns(line);

    // 遍历字符数组
    for (CFIndex runIndex = 0; runIndex < CFArrayGetCount(runArray); runIndex++)
    {
        // Get FONT for this run
        CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runArray, runIndex);
        CTFontRef runFont = CFDictionaryGetValue(CTRunGetAttributes(run), kCTFontAttributeName);

        // for each GLYPH in run
        for (CFIndex runGlyphIndex = 0; runGlyphIndex < CTRunGetGlyphCount(run); runGlyphIndex++)
        {
            // get Glyph & Glyph-data
            CFRange thisGlyphRange = CFRangeMake(runGlyphIndex, 1);
            CGGlyph glyph;
            CGPoint position;
            CTRunGetGlyphs(run, thisGlyphRange, &glyph);
            CTRunGetPositions(run, thisGlyphRange, &position);

            // Get PATH of outline
            {
                CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyph, NULL);
                CGAffineTransform t = CGAffineTransformMakeTranslation(position.x, position.y);
                CGPathAddPath(letters, &t, letter);
                CGPathRelease(letter);
            }
        }
    }
    CFRelease(line);
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointZero];
    [path appendPath:[UIBezierPath bezierPathWithCGPath:letters]];
    CGPathRelease(letters);
    CFRelease(font);
    return path;
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

原文:http://blog.csdn.net/Xoxo_x/article/details/71512943 
参考博客:http://blog.csdn.net/mydo/article/details/51620720

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值