123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- //
- // XYExpressionItemView.m
- // Starbuds
- //
- // Created by gy on 2020/8/24.
- // Copyright © 2020 翟玉磊. All rights reserved.
- //
- #import "XYExpressionItemView.h"
- #import <SVGAPlayer/SVGA.h>
- #import <FLAnimatedImage/FLAnimatedImage.h>
- #import <YYImage/YYImage.h>
- #import "XYResourceCacheManager.h"
- @interface XYExpressionItemView()<SVGAPlayerDelegate>
- @property (nonatomic, strong) SVGAPlayer *expressionPlayer;
- @property (nonatomic, strong) UIImageView *imageView;
- @property (nonatomic, strong) FLAnimatedImageView *gifImageView;
- @property (nonatomic, strong) YYAnimatedImageView *yyImageView;
- @property (nonatomic, assign) NSInteger animatedImgCount;
- @property (nonatomic, copy) NSString *expressionId;
- @property (nonatomic, copy) NSString *expressionUrl;
- /// 播放次数
- @property (nonatomic, assign) NSInteger playTimes;
- /// 停留帧数
- @property (nonatomic, assign) NSInteger finalFrame;
- /// 播放类型
- @property (nonatomic, assign) XYExpressionType expressionType;
- @property (nonatomic, strong) NSTimer *timer;
- @end
- @implementation XYExpressionItemView
- #pragma mark - Public
- - (void)reload:(XYLiveRoomMessageInfo *)info{
- self.backgroundColor = [UIColor clearColor];
- [self playExpression:info.expUrl expressionId:info.expId playTimes:info.playTimes finalFrame:info.finalFrame];
- }
- - (void)playExpression:(NSString *)expUrl expressionId:(NSString *)expressionId playTimes:(NSInteger)playTimes finalFrame:(NSInteger)finalFrame {
-
- if (StringIsEmpty(expUrl)) {
- return;
- }
-
- // 重置状态
- [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetState) object:nil];
- [self resetState];
-
- self.expressionId = expressionId;
- self.expressionUrl = expUrl;
- self.finalFrame = finalFrame;
- self.playTimes = playTimes;
- XYExpressionType expressionType = [XYExpressionItemView expressionTypeWithURL:expUrl];
-
- switch (expressionType) {
- case XYExpressionTypeSVGA:
- [self playSVGAExpression];
- break;
- case XYExpressionTypeGIF:
- [self playGIFExpression];
- break;
- default:
- [self playPNGExpression];
- break;
- }
- }
- - (void)stopAnimating {
- if (_yyImageView) {
- [_yyImageView stopAnimating];
- }
- if (_gifImageView) {
- [_gifImageView stopAnimating];
- }
- }
- - (void)clear {
- if (_timer) {
- [_timer invalidate];
- _timer = nil;
- }
- if (_imageView) {
- [_imageView removeFromSuperview];
- _imageView = nil;
- }
- if (_expressionPlayer) {
- [_expressionPlayer clear];
- [_expressionPlayer removeFromSuperview];
- _expressionPlayer = nil;
- }
- if (_gifImageView) {
- [_gifImageView stopAnimating];
- [_gifImageView removeFromSuperview];
- _gifImageView = nil;
- }
- if (_yyImageView) {
- [_yyImageView removeObserver:self forKeyPath:@"currentAnimatedImageIndex"];
- [_yyImageView stopAnimating];
- _yyImageView.image = nil;
- [_yyImageView removeFromSuperview];
- _yyImageView = nil;
- }
- }
- #pragma mark - Method
- - (void)playSVGAExpression {
-
- // 播放svga
- [[SVGAParser new] parseWithURL:UrlForString(self.expressionUrl) completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
- self.expressionPlayer.videoItem = videoItem;
- self.expressionPlayer.loops = (int)self.playTimes;
- [self.expressionPlayer startAnimation];
- } failureBlock:^(NSError * _Nullable error) {
- }];
- }
- - (void)playGIFExpression {
-
- NSData *gifData = [[XYResourceCacheManager sharedInstance] getResourceWithType:XYResourceTypeExpression URLStr:self.expressionUrl resource:self.expressionId];
- if (gifData) {
- FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:gifData];
- if (image) {
- self.gifImageView.animatedImage = image;
- }
- }else {
- [[XYResourceCacheManager sharedInstance] downloadResourceWithURLStr:self.expressionUrl resourceId:self.expressionId resourceType:XYResourceTypeExpression completeBlock:^(NSString * _Nonnull resourcePath) {
- if (StringIsNotEmpty(resourcePath)) {
- NSData *gifData = [[XYResourceCacheManager sharedInstance] getResourceWithType:XYResourceTypeExpression URLStr:self.expressionUrl resource:self.expressionId];
- FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:gifData];
- if (image) {
- self.gifImageView.animatedImage = image;
- }
- }
- }];
- }
- }
- - (void)playPNGExpression {
-
- NSData *imageData = [[XYResourceCacheManager sharedInstance] getResourceWithType:XYResourceTypeExpression URLStr:self.expressionUrl resource:self.expressionId];
- if (imageData) {
-
- YYImage *image = [YYImage imageWithData:imageData];
-
- // yyImageView就是YYAnimatedImageView
- [self.yyImageView addObserver:self forKeyPath:@"currentAnimatedImageIndex" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
-
- // animatedImgCount记录gif动图内图片的数量
- if ([image respondsToSelector:@selector(animatedImageFrameCount)]) {
- self.animatedImgCount = [image animatedImageFrameCount];
- }
-
- self.yyImageView.image = image;
-
- }else {
- [[XYResourceCacheManager sharedInstance] downloadResourceWithURLStr:self.expressionUrl resourceId:self.expressionId resourceType:XYResourceTypeExpression completeBlock:^(NSString * _Nonnull resourcePath) {
- if (StringIsNotEmpty(resourcePath)) {
- NSData *imageData = [[XYResourceCacheManager sharedInstance] getResourceWithType:XYResourceTypeExpression URLStr:self.expressionUrl resource:self.expressionId];
- // yyImageView就是YYAnimatedImageView
- [self.yyImageView addObserver:self forKeyPath:@"currentAnimatedImageIndex" options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context:nil];
-
- YYImage *image = [YYImage imageWithData:imageData];
-
- // animatedImgCount记录gif动图内图片的数量
- if ([image respondsToSelector:@selector(animatedImageFrameCount)]) {
- self.animatedImgCount = [image animatedImageFrameCount];
- }
-
- self.yyImageView.image = image;
- }
- }];
- }
- }
- // KVO监听回调
- - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
- if ([keyPath isEqualToString:@"currentAnimatedImageIndex"]) {
- if ([change[NSKeyValueChangeNewKey] respondsToSelector:@selector(integerValue)]) {
- NSInteger currentAnimatedImageIndex = [change[NSKeyValueChangeNewKey] integerValue];
- if (self.animatedImgCount > 0) {
- if (currentAnimatedImageIndex == self.animatedImgCount - 1) {
- self.playTimes--;
- if (self.playTimes == 0) {
- // 动画结束
- dispatch_async(dispatch_get_main_queue(), ^{
- [self.yyImageView stopAnimating];
- if (self.clearsAfterStop) {
- [self resetState];
- }
- });
- }
- }
- }
- else {
- [self.yyImageView stopAnimating];
- if (self.clearsAfterStop) {
- [self resetState];
- }
- }
- }
- }
- }
- + (XYExpressionType)expressionTypeWithURL:(NSString *)expURL {
- NSString *temp = [expURL pathExtension];
- if ([temp isEqualToString:@"svga"]) {
- return XYExpressionTypeSVGA;
- }
- if ([temp isEqualToString:@"gif"]) {
- return XYExpressionTypeGIF;
- }
- return XYExpressionTypePNG;
- }
- #pragma mark — SVGAPlayerDelegate
- /// 播放完成
- - (void)svgaPlayerDidFinishedAnimation:(SVGAPlayer *)player {
- if (player.tag == 1) {
- if (self.finalFrame > 0) {
- [self.expressionPlayer stepToFrame:self.finalFrame andPlay:NO];
- }else{
- //gy todo
- [self.expressionPlayer stepToPercentage:0.9 andPlay:NO];
- }
- if (self.clearsAfterStop) {
- [self hideExpression];
- }
- }
- }
- - (void)hideExpression {
- [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(resetState) object:nil];
- [self performSelector:@selector(resetState) withObject:nil afterDelay:0.5];
- }
- - (void)resetState {
- self.expressionId = @"";
- self.expressionUrl = @"";
- self.finalFrame = 0;
- self.playTimes = 1;
- self.animatedImgCount = 0;
-
- [self clear];
- }
- - (SVGAPlayer *)expressionPlayer {
- if (!_expressionPlayer) {
- _expressionPlayer = [[SVGAPlayer alloc] init];
- _expressionPlayer.delegate = self;
- _expressionPlayer.loops = 1;
- _expressionPlayer.clearsAfterStop = YES;
- _expressionPlayer.tag = 1;
- _expressionPlayer.clipsToBounds = YES;
- _expressionPlayer.frame = self.bounds;
- [self addSubview:_expressionPlayer];
- if (_expressionPlayer.f_heigh == 0 || _expressionPlayer.f_width == 0) {
- [_expressionPlayer mas_makeConstraints:^(MASConstraintMaker *make) {
- make.edges.equalTo(self);
- }];
- }
- }
- return _expressionPlayer;
- }
- - (UIImageView *)imageView{
- if (_imageView == nil) {
- _imageView = [[UIImageView alloc] init];
- _imageView.contentMode = UIViewContentModeScaleAspectFill;
- _imageView.clipsToBounds = YES;
- _imageView.frame = self.bounds;
- [self addSubview:_imageView];
- if (_imageView.f_heigh == 0 || _imageView.f_width == 0) {
- [_imageView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.edges.equalTo(self);
- }];
- }
- }
- return _imageView;
- }
- - (FLAnimatedImageView *)gifImageView {
- if (_gifImageView == nil) {
- _gifImageView = [[FLAnimatedImageView alloc] init];
- _gifImageView.contentMode = UIViewContentModeScaleAspectFill;
- _gifImageView.clipsToBounds = YES;
- _gifImageView.frame = self.bounds;
- _gifImageView.runLoopMode = NSDefaultRunLoopMode;
- [self addSubview:_gifImageView];
- if (_gifImageView.f_heigh == 0 || _gifImageView.f_width == 0) {
- [_gifImageView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.edges.equalTo(self);
- }];
- }
- WeakSelf
- [_gifImageView setLoopCompletionBlock:^(NSUInteger loopCountRemaining) {
- weakSelf.playTimes--;
- if (weakSelf.playTimes == 0) {
- [weakSelf.gifImageView stopAnimating];
- if (weakSelf.clearsAfterStop) {
- [weakSelf hideExpression];
- }
- }
- }];
- }
- return _gifImageView;
- }
- - (YYAnimatedImageView *)yyImageView {
- if (_yyImageView == nil) {
- _yyImageView = [[YYAnimatedImageView alloc] init];
- _yyImageView.contentMode = UIViewContentModeScaleAspectFill;
- _yyImageView.clipsToBounds = YES;
- _yyImageView.frame = self.bounds;
- _yyImageView.runloopMode = NSDefaultRunLoopMode;
- [self addSubview:_yyImageView];
- if (_yyImageView.f_heigh == 0 || _yyImageView.f_width == 0) {
- [_yyImageView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.edges.equalTo(self);
- }];
- }
- }
- return _yyImageView;
- }
- /*
- // Only override drawRect: if you perform custom drawing.
- // An empty implementation adversely affects performance during animation.
- - (void)drawRect:(CGRect)rect {
- // Drawing code
- }
- */
- @end
|