123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- //
- // XYLabelAnimation.m
- // Starbuds
- //
- // Created by 翟玉磊 on 2020/3/11.
- // Copyright © 2020 翟玉磊. All rights reserved.
- //
- #import "XYLabelAnimation.h"
- #import "YLSingleText.h"
- @interface XYLabelAnimation ()
- @property (nonatomic, strong) NSMutableArray <YLSingleText *>*allText;
- @property (nonatomic, strong) CADisplayLink *time;
- @property (nonatomic, assign) int loopCount;
- @property (nonatomic, assign) int steps;
- @end
- @implementation XYLabelAnimation
- @synthesize text = _text;
- @synthesize attributedText = _attributedText;
- - (instancetype)initWithCoder:(NSCoder *)coder
- {
- self = [super initWithCoder:coder];
- if (self) {
- [self prepare];
- [self setNeedsDisplay];
- }
- return self;
- }
- - (instancetype)initWithFrame:(CGRect)frame attributedText:(NSAttributedString *)attributedText
- {
- self = [super initWithFrame:frame];
- if (self) {
- [self prepare];
- self.attributedText = attributedText;
- }
- return self;
- }
- - (instancetype)initWithFrame:(CGRect)frame text:(NSString *)text
- {
- self = [super initWithFrame:frame];
- if (self) {
- [self prepare];
- self.text = text;
- }
- return self;
- }
- - (void)prepare
- {
- self.loopCount = -1;
- }
- - (void)sizeToFit
- {
- [self setFrame:({
- CGFloat x = self.frame.origin.x;
- CGFloat y = self.frame.origin.y;
- CGFloat width = self.kerning * self.allText.count;
- CGFloat height = self.font.ascender - self.font.descender + self.animationHeight;
- CGRectMake(x, y, width, height);
- })];
- }
- - (void)start
- {
- self.steps = 0;
- self.steps ++;
- if (self.steps % 3 == 0 || self.steps % 3 == 1 ) {
- [self setNeedsDisplay];
- }
- if (self.steps > 1000) {
- self.steps = 0;
- }
- }
- - (void)startAnimation
- {
- [self.time invalidate];
- self.time = [CADisplayLink displayLinkWithTarget:self selector:@selector(start)];
- [self.time addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
- }
- - (void)pauseAnimation
- {
- [self.time invalidate];
- self.time = nil;
- }
- - (void)stopAnimation
- {
- [self pauseAnimation];
- self.loopCount = -1;
- [self.allText makeObjectsPerformSelector:@selector(normalReset)];
- [self.allText makeObjectsPerformSelector:@selector(waveReset)];
- [self setNeedsDisplay];
- }
- - (void)drawRect:(CGRect)rect {
- __block CGFloat x = 0;
- __weak typeof(self) weakSelf = self;
- [self.allText enumerateObjectsUsingBlock:^(YLSingleText *singleText, NSUInteger idx, BOOL *stop) {
- CGFloat location = 0;
-
- // 仅仅在能第一次遍历玩所有的文字的时候调用
- if (self.loopCount == idx * weakSelf.rate) {
- location = [singleText locationWithFirstEnumerate];
- }else{
- // 让其他的文字在一开始的时候不要动
- location = 0;
- }
- // 已经被遍历过的标志
- if (singleText.enumerated) {
- // 判断动画模式
- if (weakSelf.type) {
- location = [singleText locationWithWaveAnimationCompletion:^{
- if (idx == weakSelf.allText.count - 1) {
- [weakSelf.allText makeObjectsPerformSelector:@selector(waveReset)];
- self.loopCount = -1;
- }
- }];
- } else {
- location = [singleText locationWithNormalAnimation];
- }
- }
- CGFloat trueLocation = weakSelf.animationHeight - location;
- CGRect trueRect = CGRectMake(x, trueLocation, weakSelf.textSize, weakSelf.textSize);
- NSMutableDictionary *attibutes = [NSMutableDictionary dictionary];
- attibutes[NSFontAttributeName] = weakSelf.font;
- attibutes[NSForegroundColorAttributeName] = singleText.textColor;
- [singleText.text drawInRect:trueRect withAttributes:attibutes];
- x += weakSelf.kerning;
- }];
- self.loopCount ++;
- }
- #pragma mark -
- #pragma mark setter && getter
- - (CGFloat)textSize
- {
- return self.font.pointSize + self.animationHeight;
- }
- - (void)setText:(NSString *)text
- {
- _text = text;
-
- [self.allText removeAllObjects];
- for (int i = 0; i < text.length; ++i) {
-
- YLSingleText *singleText = [YLSingleText singleTextWithAnimationRange: text.length];
- singleText.text = [text substringWithRange:NSMakeRange(i, 1)];
- singleText.textColor = self.textColor;
- [self.allText addObject:singleText];
- }
- [self sizeToFit];
- [self setNeedsDisplay];
- }
- - (void)setAttributedText:(NSAttributedString *)attributedText
- {
- [super setAttributedText:attributedText];
- [self.allText removeAllObjects];
- for (int i = 0; i < attributedText.length; ++i) {
-
- YLSingleText *singleText = [YLSingleText singleTextWithAnimationRange: attributedText.length];
- singleText.text = [attributedText.string substringWithRange:NSMakeRange(i, 1)];
- NSDictionary *attributed = [attributedText attributesAtIndex:i effectiveRange:nil];
- singleText.textColor = attributed[NSForegroundColorAttributeName];
- [self.allText addObject:singleText];
- }
- [self sizeToFit];
- [self setNeedsDisplay];
- }
- - (void)setType:(XYLabelAnimationType)type
- {
- _type = type;
- self.loopCount = -1;
- [self.allText makeObjectsPerformSelector:@selector(normalReset)];
- [self.allText makeObjectsPerformSelector:@selector(waveReset)];
- }
- - (CGFloat)kerning
- {
- return _kerning + self.font.pointSize;
- }
- - (NSUInteger)rate
- {
- if (!_rate) {
- _rate = 2;
- }
- if (_rate < 1) {
- _rate = 1;
- }
- if (_rate > 10) {
- _rate = 10;
- }
- return _rate;
- }
- //- (UIFont *)font
- //{
- // if (![super font]) {
- // return [UIFont systemFontOfSize:15];
- // }
- // return [super font];
- //}
- @synthesize animationHeight = _animationHeight;
- - (void)setAnimationHeight:(CGFloat)animationHeight
- {
- _animationHeight = animationHeight + self.font.pointSize;
- }
- - (CGFloat)animationHeight
- {
- if (!_animationHeight) {
- _animationHeight = self.font.pointSize;
- }
- return _animationHeight;
- }
- - (NSMutableArray<YLSingleText *> *)allText
- {
- if (!_allText) {
- _allText = [@[] mutableCopy];
- }
- return _allText;
- }
- @end
|