1. 程式人生 > >最簡單的直播禮物連刷特效製作(帶原始碼)

最簡單的直播禮物連刷特效製作(帶原始碼)

直播禮物連刷能有效的提升主播與使用者的互動,從而提升使用者刷禮物的數量,那現在咱們來做一個簡單的直播禮物連刷教程吧。

先貼出效果圖:


1. 首先從簡單的開始,文字描邊+連擊效果,這個比較簡單,只要重寫 UILabel 的



- (void)drawTextInRect:(CGRect)rect
就可以達到文字描邊的效果;然後開定時器,讓數字增加,動畫效果用關鍵幀動畫控制。


2. 然後仿照映客的 UI 自定義 View ,控制動畫,從螢幕外面進入,然後顯示連擊效果,最後隱藏,恢復到初始位置。


3. 上面的動畫效果只要稍微有點動畫基礎,很容易就搞定了。做到這裡我冷靜下來,不再往下面做了,因為事情遠遠沒有想象的那麼簡單。首先考慮的是,在收到禮物訊息的回撥時去賦值資料來源,執行動畫,但是這個回撥是是一個字典陣列,裡面包含了一段時間內多條訊息,他們是有順序的,這是其一;其二,這個回撥呼叫次數會很頻繁,短時間內就會收到更多的訊息陣列。所以需要把這些訊息處理成佇列,然後播放動畫效果,一個動畫效果播放完成後,再從訊息佇列中取下一個訊息,繼續播放下一個動畫,這樣才能保證動畫的播放順序不回亂。


說到佇列的話就想到了多執行緒,NSOperation ,我們可以重寫它,然後在 start 方法中新增動畫,但是注意我們只是需要讓這些訊息排隊,更新 UI 還是要在主執行緒操作;我們還要手動觸發 NSOperation 的 KVO,告訴這個操作什麼時候開始,什麼時候算是結束,我們想在一個動畫播放完畢後再執行下一個動畫,於是我這裡定義了一個 block ,在動畫結束時,傳遞給 NSOperation ,告訴它動畫結束了。


@synthesize finished = _finished;
@synthesize executing = _executing;
- (instancetype)init
{
    self = [super init];
    if (self) {
        _executing = NO;
        _finished  = NO;
    }
    return self;
}
- (void)start {
    if ([self isCancelled]) {
        self.finished = YES;
        return;
    }
    self.executing = YES;
    
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        _presentView = [[PresentView alloc] init];
        _presentView.model = _model;
        // i % 2 控制最多允許出現幾行
        _presentView.frame = CGRectMake(-self.listView.frame.size.width / 2, 300 - (_index % 2) * 70, self.listView.frame.size.width / 2, 40);
        _presentView.originFrame = _presentView.frame;
        [self.listView addSubview:_presentView];
        [self.presentView animateWithCompleteBlock:^(BOOL finished) {
            self.finished = finished;
        }];
    }];
    
}
#pragma mark -  手動觸發 KVO
- (void)setExecuting:(BOOL)executing
{
    [self willChangeValueForKey:@"isExecuting"];
    _executing = executing;
    [self didChangeValueForKey:@"isExecuting"];
}
- (void)setFinished:(BOOL)finished
{
    [self willChangeValueForKey:@"isFinished"];
    _finished = finished;
    [self didChangeValueForKey:@"isFinished"];
}
注意這裡 :


_presentView.frame = CGRectMake(-self.listView.frame.size.width / 2, 300 - (_index % 2) * 70, self.listView.frame.size.width / 2, 40);// i % 2 控制最多允許出現幾行
queue.maxConcurrentOperationCount = 2; // 佇列分發


當時其實只是實現了一個佇列,按順序一個一個播放,如何實現 N 列併發呢?其實把這些併發的動畫佇列想象成圖片的多併發非同步下載就好了,下意識地就加了上面兩句控制併發列數的程式碼。能這麼順利做出來,是因為最近仔細研究了 SDWebImage 的原始碼,不覺得重寫 NSOperation 那個方式很熟悉麼~哈哈。最近工作忙,動畫的細節和封裝性沒有再完善,不過易用性我感覺還是很好的,祝大家玩得開心~

github原始碼:https://github.com/aiyaapp/AiyaEffectsIOS