iOS重拾直播系列-直播間禮物效果

直播問題交流可加群 379258188 備注簡書

之前寫過直播間的禮物效果的文章
iOS開發(fā) - Lottie實(shí)現(xiàn)直播間禮物特效
iOS開發(fā)-SVGA Animation實(shí)現(xiàn)直播間禮物特效
上面兩篇只是對LottieSVGA的簡單介紹

本次主要是結(jié)合我們上線直播項(xiàng)目對SVGA的使用,直播間接收到禮物消息之后,禮物效果要依次展示!
主要方式是創(chuàng)建一個(gè)SvgaManager,里面維護(hù)一個(gè)NSMutableArray,數(shù)組里存放的是禮物的信息,等待一個(gè)動(dòng)畫執(zhí)行完成之后,再執(zhí)行下一個(gè)動(dòng)畫!

SVGAPlayer

創(chuàng)建SVGACustomPlayer繼承SVGAPlayer,SVGAPlayer本身是UIView,重寫下面的方法,讓禮物效果不接受事件

/**
 每個(gè)view都有這個(gè)方法兼贡,用來處理用戶的操作事件容劳。
 @return 它返回:self丑念,代表這個(gè)view會(huì)接受用戶的操作事件,返回:nil倚搬,則代表這個(gè)view不會(huì)接受用戶的操作事件蹂窖。
 */

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    return nil;
}

SvgaManager

  • SvgaManager.h
typedef NS_ENUM(NSInteger, SvgaMgrType)
{
    SvgaMgrTypeGifts = 0, //類型禮物
    SvgaMgrTypeMounts,    //進(jìn)場動(dòng)畫
};


@interface SvgaManager : NSObject
/**
 單個(gè)動(dòng)畫循環(huán)次數(shù)
 */
@property (nonatomic, assign) NSInteger loops;

@property (nonatomic, assign) BOOL clearsAfterStop;

@property (nonatomic, assign) SvgaMgrType type;

@property (nonatomic, strong) SVGACustomPlayer *aPlayer; //Tag 禮物:0  座駕:1  用于區(qū)分


/**
 添加svga動(dòng)畫 等待執(zhí)行
 
 @param model svga動(dòng)畫關(guān)聯(lián)數(shù)據(jù)
 */
-(void)loadSvgaItem:(SvgaMgrModel *)model superview:(UIView *)view SVGAFrame:(CGRect)rect;

@end

  • SvgaManager.m
@interface SvgaManager()<SVGAPlayerDelegate>

@property (nonatomic, assign)BOOL isPlay;

@property (nonatomic, strong) SVGAParser *aParser;

/**
 存放需要執(zhí)行的svga動(dòng)畫
 */
@property (nonatomic, strong) NSMutableArray<SvgaMgrModel *>* svgaItems;

@property (nonatomic, strong) UIView *tempSuperView;
// 是否是禮物操作
@property (nonatomic, assign) BOOL isGiftSvga;

// 是否是座駕操作
@property (nonatomic, assign) BOOL isMountsSvga;

@end

@implementation SvgaManager

- (instancetype)init {
    if (self = [super init]) {
        self.isGiftSvga = NO;
        self.isMountsSvga = NO;
    }
    return self;
}

- (void)loadSvgaItem:(SvgaMgrModel *)model superview:(UIView *)view SVGAFrame:(CGRect)rect {
    
    self.tempSuperView = view;
    
    // 緩存數(shù)據(jù)
    [self.svgaItems addObject:model];
    
    if (self.type == SvgaMgrTypeMounts) { // 進(jìn)場特效
        
        [view addSubview:self.aPlayer];
        [self aPlayerSet:rect];
        
    }else{ // 禮物效果
        
        // 根據(jù)需求,是否需要修改禮物圖層順序
        for (UIView *svgaView in view.subviews) {
            
            if ([svgaView isKindOfClass:[SVGAPlayer class]] && svgaView.tag == 1) { // 這里直播間存在進(jìn)場特效
                [view insertSubview:self.aPlayer belowSubview:svgaView];
                [self aPlayerSet:rect];
                return;
            }
        }
        
        // 正常情況
        [view addSubview:self.aPlayer];
        [self aPlayerSet:rect];
        
    }
    
    
}

- (void)aPlayerSet:(CGRect)rect{
    
    self.aPlayer.frame = rect;
    self.aPlayer.loops = (int)self.loops;
    self.aPlayer.clearsAfterStop = self.clearsAfterStop;
    
    if (self.isPlay != YES) {
        [self playSvga];
    }
}

#pragma mark - Private
- (void)playSvga {
    
    
    if (self.svgaItems.count == 0 ) { //隊(duì)列中不存在效果
        return;
    }
    
    self.isPlay = YES;
    __weak typeof(self) weakSelf = self;
    
    SvgaMgrModel * model = self.svgaItems.firstObject;
    
    // 執(zhí)行動(dòng)畫
    [self.aParser parseWithURL:[NSURL URLWithString:model.svgaUrl] completionBlock:^(SVGAVideoEntity * _Nullable videoItem) {
        
        if (videoItem) {
            
            weakSelf.aPlayer.videoItem = videoItem;
            [weakSelf.aPlayer startAnimation];
            self.isGiftSvga = YES;
            
            if (self.type == SvgaMgrTypeMounts) { // 這里入場動(dòng)畫的文字特效
                self.isMountsSvga = YES;
                [self showMounstView:model];
            }
            
            if (weakSelf.svgaItems.count > 0) {
                [weakSelf.svgaItems removeFirstObject];
            }
        }
        
    } failureBlock:^(NSError * _Nullable error) {
        
    }];
    
}

// 執(zhí)行特效文字
- (void)showMounstView:(SvgaMgrModel *)model {
    // TODO:
}

#pragma mark - <SVGAPlayerDelegate>
- (void)svgaPlayerDidFinishedAnimation:(SVGAPlayer *)player {
    
    if (self.svgaItems.count == 0) {
        
        [self.aPlayer removeFromSuperview];
        self.isGiftSvga = NO;
        
        if (self.isMountsSvga == NO && self.isGiftSvga == NO) {
            self.isPlay = NO;
        }
        
    }else{
        
        self.isGiftSvga = NO;
        
//        if (self.type == SvgaMgrTypeGifts && self.isGiftSvga == NO) {
//            [self playSvga];
//        }else if (self.type == SvgaMgrTypeMounts && self.isMountsSvga == NO){
//            [self playSvga];
//        }
        
        if (self.isMountsSvga == NO && self.isGiftSvga == NO) {
            [self playSvga];
        }
    }
    
}

- (void)dealloc{
    
    DLog(@"內(nèi)存已經(jīng)釋放");
}

#pragma mark - setter/getter
- (SVGACustomPlayer *)aPlayer {
    
    if (_aPlayer == nil) {
        _aPlayer = [[SVGACustomPlayer alloc] init];
        _aPlayer.delegate = self;
        _aPlayer.contentMode = UIViewContentModeScaleAspectFit;
    }
    return _aPlayer;
}

- (SVGAParser *)aParser{
    
    if (_aParser == nil) {
        _aParser = [[SVGAParser alloc]init];
    }
    
    return _aParser;
}

- (NSMutableArray<SvgaMgrModel *> *)svgaItems {
    
    if (_svgaItems == nil) {
        _svgaItems = [NSMutableArray array];
    }
    return _svgaItems;
}

@end

上述的SvgaManager也對進(jìn)場特效進(jìn)行的出去

如何使用:
懶加載Manager

- (SvgaManager *)giftSvgaManager {
    if (_giftSvgaManager == nil) {
        _giftSvgaManager = [[SvgaManager alloc]init];
        _giftSvgaManager.type = SvgaMgrTypeGifts;
        _giftSvgaManager.aPlayer.tag = 0;
        _giftSvgaManager.clearsAfterStop = YES;
        _giftSvgaManager.loops = 1;
    }
    return _giftSvgaManager;
}

接收到消息的時(shí)候

// model中還有其他的屬性,比如用戶信息用于進(jìn)場動(dòng)畫
 SvgaMgrModel *model = [[SvgaMgrModel alloc]init];
 model.svgaUrl = @"";
[self.giftSvgaManager loadSvgaItem:model superview:self.view SVGAFrame:self.view.frame];

模擬一下禮物消息

    NSArray *items = @[
                       @"https://github.com/yyued/SVGA-Samples/blob/master/EmptyState.svga?raw=true",
                       @"https://github.com/yyued/SVGA-Samples/blob/master/HamburgerArrow.svga?raw=true",
                       @"https://github.com/yyued/SVGA-Samples/blob/master/PinJump.svga?raw=true",
                       @"https://github.com/yyued/SVGA-Samples/blob/master/TwitterHeart.svga?raw=true",
                       @"https://github.com/yyued/SVGA-Samples/blob/master/Walkthrough.svga?raw=true",
                       @"https://github.com/yyued/SVGA-Samples/blob/master/angel.svga?raw=true",
                       @"https://github.com/yyued/SVGA-Samples/blob/master/halloween.svga?raw=true",
                       @"https://github.com/yyued/SVGA-Samples/blob/master/kingset.svga?raw=true",
                       @"https://github.com/yyued/SVGA-Samples/blob/master/posche.svga?raw=true",
                       @"https://github.com/yyued/SVGA-Samples/blob/master/rose.svga?raw=true",
                       ];
    SvgaMgrModel *model = [[SvgaMgrModel alloc]init];
    model.svgaUrl = items[arc4random() % 10];
    [self.giftSvgaManager loadSvgaItem:model superview:self.view SVGAFrame:self.view.frame];

本文demo https://github.com/TsuiOS/HsuLive

上面的SVGA文件是存放再github上的,訪問很慢! 我在七牛上也上傳了一份,加載速度明顯提升

http://phq4iiqb5.bkt.clouddn.com/HamburgerArrow.svga
http://phq4iiqb5.bkt.clouddn.com/Walkthrough.svga
http://phq4iiqb5.bkt.clouddn.com/PinJump.svga
http://phq4iiqb5.bkt.clouddn.com/EmptyState.svga
http://phq4iiqb5.bkt.clouddn.com/heartbeat.svga
http://phq4iiqb5.bkt.clouddn.com/halloween.svga
http://phq4iiqb5.bkt.clouddn.com/posche.svga
http://phq4iiqb5.bkt.clouddn.com/kingset.svga
http://phq4iiqb5.bkt.clouddn.com/TwitterHeart.svga
http://phq4iiqb5.bkt.clouddn.com/angel.svga
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末欣福,一起剝皮案震驚了整個(gè)濱河市绢片,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌夫椭,老刑警劉巖掸掸,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蹭秋,居然都是意外死亡扰付,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門仁讨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羽莺,“玉大人,你說我怎么就攤上這事洞豁⊙喂蹋” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵丈挟,是天一觀的道長刁卜。 經(jīng)常有香客問我,道長曙咽,這世上最難降的妖魔是什么蛔趴? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮例朱,結(jié)果婚禮上孝情,老公的妹妹穿的比我還像新娘鱼蝉。我一直安慰自己,他們只是感情好箫荡,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布魁亦。 她就那樣靜靜地躺著,像睡著了一般羔挡。 火紅的嫁衣襯著肌膚如雪洁奈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天绞灼,我揣著相機(jī)與錄音睬魂,去河邊找鬼。 笑死镀赌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的际跪。 我是一名探鬼主播商佛,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼姆打!你這毒婦竟也來了良姆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤幔戏,失蹤者是張志新(化名)和其女友劉穎玛追,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闲延,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痊剖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了垒玲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陆馁。...
    茶點(diǎn)故事閱讀 38,577評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖合愈,靈堂內(nèi)的尸體忽然破棺而出叮贩,到底是詐尸還是另有隱情,我是刑警寧澤佛析,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布益老,位于F島的核電站,受9級特大地震影響寸莫,放射性物質(zhì)發(fā)生泄漏捺萌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一储狭、第九天 我趴在偏房一處隱蔽的房頂上張望互婿。 院中可真熱鬧捣郊,春花似錦、人聲如沸慈参。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽驮配。三九已至娘扩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間壮锻,已是汗流浹背琐旁。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留猜绣,地道東北人灰殴。 一個(gè)月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像掰邢,于是被迫代替她去往敵國和親牺陶。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評論 2 348