iOS FLAnimatedImage控制Gif播放次數(shù)

新手入門
請多指教

前言

要展示gif圖片啊,但是UI提供的gif圖是循環(huán)的,這邊需求gif只在打開的時候播放一次就行。

分析

FLAnimatedImage直接讀取了gif本身的循環(huán)次數(shù),并賦值給了loopCount字段。本意想著,這多簡單,直接改下loopCount就完事了,結(jié)果發(fā)現(xiàn)這個字段是readonly。。。只允許在初始化的時候賦值,通過查看源碼,該值是直接從gif圖片數(shù)據(jù)中解析而來,沒有其它的干擾其值的方式。

//
//  FLAnimatedImage.h
//  Flipboard
//  源碼

@property (nonatomic, assign, readonly) NSUInteger loopCount; // 0 means repeating the animation indefinitely

================================

//
//  FLAnimatedImage.m
//  Flipboard
//  源碼

        // Get `LoopCount`
        // Note: 0 means repeating the animation indefinitely.
        // Image properties example:
        // {
        //     FileSize = 314446;
        //     "{GIF}" = {
        //         HasGlobalColorMap = 1;
        //         LoopCount = 0;
        //     };
        // }
        NSDictionary *imageProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyProperties(_imageSource, NULL);
        _loopCount = [[[imageProperties objectForKey:(id)kCGImagePropertyGIFDictionary] objectForKey:(id)kCGImagePropertyGIFLoopCount] unsignedIntegerValue];


網(wǎng)上確實(shí)不少人建議直接把readonly改成可讀寫。這樣自己想怎么循環(huán)就怎么循環(huán)了。

但是,這樣需要更改的是FLAnimatedImage.h文件,對以后的FLAnimatedImage升級和維護(hù)都可能存在隱患。

解決方式

Note: 0 means repeating the animation indefinitely.
注:0 意味著循環(huán)播放,其它值則為播放次數(shù)。

1. 暴力解決(不建議)

直接改loopCount的屬性,去掉只讀的屬性。
然后自己想怎么賦值就怎么賦值了。
不過剛才也說過了,存在升級隱患,非常不建議,但也不失為一種方式。

//
//  FLAnimatedImage.h
//  Flipboard
//  源碼

@property (nonatomic, assign) NSUInteger loopCount; // 0 means repeating the animation indefinitely


===========================
// 實(shí)際使用時
FLAnimatedImage *gifImage = [FLAnimatedImage animatedImageWithGIFData:[NSData dataWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"gifTest" withExtension:@"gif"]]];
gifImage.loopCount = 1;

FLAnimatedImageView *gifView = [[FLAnimatedImageView alloc] init];
gifView.animatedImage = gifImage;
[self.view addSubview:gifView];

2. 換個Gif 圖(灰常推薦)

哈哈,讓UI重新出一套需求要求的Gif圖,簡單省事。

3. 使用setLoopCompletionBlock監(jiān)控

該block為Gif動畫每執(zhí)行完一次的回調(diào)。
每次執(zhí)行完之后,可以根據(jù)loopCount或者自行計數(shù)來覺得繼續(xù)執(zhí)行亦或者停止執(zhí)行。
下方為將循環(huán)播放的gif執(zhí)行完一次之后關(guān)閉執(zhí)行的操作,代碼僅供參考。

    [gifView setLoopCompletionBlock:^(NSUInteger loopCountRemaining) {
        // 判斷是循環(huán)播放,并且當(dāng)前仍在播放,則停止gif
        if (weakSelf.gifView.animatedImage.loopCount == 0 && weakSelf.gifView.isAnimating) {
            [weakSelf.gifView stopAnimating];
        }
    }];

將不循環(huán)的gif,設(shè)置為循環(huán)。
這里因?yàn)楦鞣N相關(guān)值都是readonly狀態(tài),在不改源碼的情況下很難修改對應(yīng)的值,所以考慮重置所有的值,將animatedImage的值重新賦值給FLAnimatedImageView.令其重新播放gif。目前尚不確認(rèn)內(nèi)存會出現(xiàn)頻繁抖動。希望參考的小伙伴慎重考慮。

    [_gifView setLoopCompletionBlock:^(NSUInteger loopCountRemaining) {
        // loopCount !=0 為不循環(huán),
        if (weakSelf.gifView.animatedImage.loopCount != 0) {
            // stop 當(dāng)前 animatedImage
            [weakSelf.gifView stopAnimating];

            // 取出animatdImage重新賦值給imageView以重置readonly的loopCount等值
            FLAnimatedImage *image = weakSelf.gifView.animatedImage;
            weakSelf.gifView.animatedImage = nil;

            weakSelf.gifView.animatedImage = image;
        }
    }];

4. 考慮使用動畫

想了一想,如果不是必須要求使用Gif的情況,可以考慮從Gif中抽取幀,做成原生的幀動畫,或者使用其它屬性動畫完成一樣的效果,這個要結(jié)合實(shí)際需求來做。

參考文獻(xiàn)

FLAnimatedImage (https://github.com/Flipboard/FLAnimatedImage);

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容