動(dòng)畫:CAAnimation使用
使用動(dòng)畫來寫名字镐躲!
技術(shù)點(diǎn) {?
// 先導(dǎo)進(jìn)#import 頭文件 使用CAShapeLayer結(jié)合UIBezierPath畫圓侍筛,然后再結(jié)合CAAnimatio執(zhí)行畫圓動(dòng)畫 }
//? shapeLayer.lineJoin = kCALineJoinBevel;
//? lineJoin:要使用的接合類型
//? kCGLineJoinMiter//? 接合點(diǎn)為尖角。這是默認(rèn)的接合類型裆熙。
//? kCGLineJoinBevel
//? 接合點(diǎn)為斜角
//? kCGLineJoinRound//? 接合點(diǎn)為圓角
實(shí)例:
#import "ViewController.h"
#import@interface ViewController ()
@property (nonatomic, strong) CALayer *penLayer;
@property (nonatomic, weak) CAShapeLayer *shapeLayer;
@property (nonatomic, weak) UITextField *nameTitleFile;
@property (nonatomic, weak) UIButton *determineButton;
@end
@implementation ViewController
#pragma mark - Control
- (CAShapeLayer *)shapeLayer
{
if (!_shapeLayer)
{
CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
shapeLayer.frame = self.view.bounds;
shapeLayer.geometryFlipped = YES;//翻轉(zhuǎn)
shapeLayer.strokeColor = [[UIColor blackColor] CGColor];
shapeLayer.fillColor = nil;
shapeLayer.lineWidth = 3.0f;
shapeLayer.lineJoin = kCALineJoinBevel;
self.shapeLayer = shapeLayer;
[self.view.layer addSublayer:shapeLayer];
}
return _shapeLayer;
}
- (UITextField *)nameTitleFile
{
if (!_nameTitleFile)
{
UITextField *nameTitleFile = [[UITextField alloc] init];
nameTitleFile.frame = CGRectMake(10, 64, [UIScreen mainScreen].bounds.size.width - 20, 44);
nameTitleFile.layer.borderWidth = 0.5f;
nameTitleFile.layer.borderColor = [UIColor grayColor].CGColor;
nameTitleFile.placeholder = @"請輸入名稱";
nameTitleFile.font = [UIFont systemFontOfSize:13];
self.nameTitleFile = nameTitleFile;
[self.view addSubview:nameTitleFile];
}
return _nameTitleFile;
}
- (UIButton *)determineButton
{
if (!_determineButton)
{
UIButton *determineButton = [[UIButton alloc] init];
determineButton.frame = CGRectMake(10, 118, [UIScreen mainScreen].bounds.size.width - 20, 44);
[determineButton setTitle:@"確定" forState:UIControlStateNormal];
[determineButton setBackgroundColor:[UIColor redColor]];
[determineButton addTarget:self action:@selector(determineButtonClick) forControlEvents:UIControlEventTouchUpInside];
self.determineButton = determineButton;
[self.view addSubview:determineButton];
}
return _determineButton;
}
#pragma mark - LfileCycle
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"名字簽寫";
self.nameTitleFile.delegate = self;
self.determineButton;
}
#pragma mark - Touch Event
- (void)determineButtonClick
{
[self setupTextLayer];
[self startAnimation];
}
#pragma mark - setupTextLayer
- (void)setupTextLayer
{
if (self.shapeLayer != nil)
{
[self.penLayer removeFromSuperlayer];
[self.shapeLayer removeFromSuperlayer];
self.shapeLayer = nil;
self.penLayer = nil;
}
// 曲線動(dòng)畫的path
CGMutablePathRef letters = CGPathCreateMutable();
// 文字格式和大小
CTFontRef font = CTFontCreateWithName(CFSTR("Helvetica-Bold"), 46.0, NULL);
NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:
(__bridge id)font, kCTFontAttributeName,nil];
// 文字
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:self.nameTitleFile.text
attributes:attrs];
// 參考線
CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef)attrString);
// CTLineGetGlyphRuns:構(gòu)成線的ctrun對(duì)象。
CFArrayRef runArray = CTLineGetGlyphRuns(line);
// 每次運(yùn)行
for (CFIndex runIndex = 0; runIndex < CFArrayGetCount(runArray); runIndex++)
{
// 獲取運(yùn)行的字體,
// CTRunRef:運(yùn)行參考
CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runArray, runIndex);
CTFontRef runFont = CFDictionaryGetValue(CTRunGetAttributes(run), kCTFontAttributeName);
// 對(duì)于運(yùn)行中的每個(gè)符號(hào)
// CTRunGetGlyphCount:運(yùn)行獲得字形計(jì)數(shù)
for (CFIndex runGlyphIndex = 0; runGlyphIndex < CTRunGetGlyphCount(run); runGlyphIndex++)
{
// 獲取字形和字形數(shù)據(jù)
CFRange thisGlyphRange = CFRangeMake(runGlyphIndex, 1);// 范圍
CGGlyph glyph;// 雕文
CGPoint position;// 位置
CTRunGetGlyphs(run, thisGlyphRange, &glyph);
CTRunGetPositions(run, thisGlyphRange, &position);
// 獲取輪廓路徑
{
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);
self.shapeLayer.path = path.CGPath;
self.shapeLayer.bounds = CGPathGetBoundingBox(path.CGPath);
UIImage *penImage = [UIImage imageNamed:@"noun_project_347_2.png"];
CALayer *penLayer = [CALayer layer];
penLayer.contents = (id)penImage.CGImage;
penLayer.anchorPoint = CGPointZero;
penLayer.frame = CGRectMake(0.0f, 0.0f, penImage.size.width, penImage.size.height);
[self.shapeLayer addSublayer:penLayer];
self.penLayer = penLayer;
}
#pragma mark - startAnimation
- (void)startAnimation
{
[self.shapeLayer removeAllAnimations];
[self.penLayer removeAllAnimations];
self.penLayer.hidden = NO;
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnimation.duration = 10.0;
pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
[self.shapeLayer addAnimation:pathAnimation forKey:@"strokeEnd"];
CAKeyframeAnimation *penAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
penAnimation.duration = 10.0;
penAnimation.path = self.shapeLayer.path;
penAnimation.calculationMode = kCAAnimationPaced;
penAnimation.delegate = self;
penAnimation.removedOnCompletion = NO;
penAnimation.fillMode = kCAFillModeForwards;
[self.penLayer addAnimation:penAnimation forKey:@"position"];
}
@end
githubDemo:https://github.com/EvanYeShao/Animation-write-name