版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2017.09.16 |
前言
app中好的炫的動畫可以讓用戶耳目一新丈屹,為產(chǎn)品增色不少,關于動畫的實現(xiàn)我們可以用基本動畫伶棒、關鍵幀動畫旺垒、序列幀動畫以及基于CoreGraphic的動畫等等,接下來這幾篇我就介紹下我可以想到的幾種動畫繪制方法肤无。具體Demo示例已開源到Github —— 刀客傳奇先蒋,感興趣的可以看我寫的另外幾篇。
1. 實現(xiàn)動畫方式深度解析(一) —— 播放GIF動畫(一)
FLAnimatedImage框架作者
上一篇我們介紹了播放GIF動畫的幾種方式宛渐,其中特意提到使用FLAnimatedImage
框架播放動畫鞭达,為了層次清晰司忱,所以另外開幾篇進行單獨講解,這一篇我們就開始講一下利用FLAnimatedImage
播放GIF動畫畴蹭。
首先我們看一下作者坦仍。
最新的star統(tǒng)計數(shù)目是6k+,他們是四個人在維護這個框架叨襟。
基本介紹
FLAnimatedImage是一種高性能的iOS GiF動畫引擎繁扎,主要體現(xiàn)在下面幾個方面。
- 以與桌面瀏覽器相當?shù)牟シ潘俣韧瑫r播放多個GIF
- 可變的幀延遲
- 在有內存方面壓力還是很好的運行
- 在第一個回放循環(huán)中消除延遲或阻塞
- 以現(xiàn)代瀏覽器的方式解釋快速GIF的幀延遲
看一個示例
1. 安裝與使用
FLAnimatedImage是一個很好封裝的插件組件糊闽。 簡單地將UIImageView
實例替換為FLAnimatedImageView
的實例梳玫,以獲得動畫GIF支持。 沒有中央緩存或狀態(tài)來管理右犹。
- 使用Cocoapods安裝管理
$ pod try FLAnimatedImage
把他加入到您的app提澎,復制兩個類FLAnimatedImage.h/.m
和 FLAnimatedImageView.h/.m
到您的xcode工程,或者通過Cocoapods命令行集成念链。
pod 'FLAnimatedImage', '~> 1.0'
- 使用Carthage
github "Flipboard/FLAnimatedImage"
在你的xcode中盼忌,#import "FLAnimatedImage.h"
,從一個Gif動畫創(chuàng)建一個image掂墓,并展示它谦纱。
FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif"]]];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = image;
imageView.frame = CGRectMake(0.0, 0.0, 100.0, 100.0);
[self.view addSubview:imageView];
它兼容iOS6,并涉及到下面這些框架君编。
QuartzCore
ImageIO
MobileCoreServices
CoreGraphics
它能夠進行細粒度日志記錄跨嘉,可以在FLAnimatedImage上設置一個塊,當通過調用方法+ setLogBlock:logLevel:
時吃嘿,可以記錄發(fā)生的各種日志級別祠乃。 例如:
// Set up FLAnimatedImage logging.
[FLAnimatedImage setLogBlock:^(NSString *logString, FLLogLevel logLevel) {
// Using NSLog
NSLog(@"%@", logString);
// ...or CocoaLumberjackLogger only logging warnings and errors
if (logLevel == FLLogLevelError) {
DDLogError(@"%@", logString);
} else if (logLevel == FLLogLevelWarn) {
DDLogWarn(@"%@", logString);
}
} logLevel:FLLogLevelWarn];
框架結構及API接口
下面我們就看一下該框架的框架結構
大家可以看到,這個框架很輕量級兑燥×链桑框架的工作原理及流程如下所示。
接著我們看一下API接口
1. FLAnimatedImage.h
這里面包含了好幾個接口
@interface FLAnimatedImage : NSObject
@property (nonatomic, strong, readonly) UIImage *posterImage; // Guaranteed to be loaded; usually equivalent to `-imageLazilyCachedAtIndex:0`
@property (nonatomic, assign, readonly) CGSize size; // The `.posterImage`'s `.size`
@property (nonatomic, assign, readonly) NSUInteger loopCount; // 0 means repeating the animation indefinitely
@property (nonatomic, strong, readonly) NSDictionary *delayTimesForIndexes; // Of type `NSTimeInterval` boxed in `NSNumber`s
@property (nonatomic, assign, readonly) NSUInteger frameCount; // Number of valid frames; equal to `[.delayTimes count]`
@property (nonatomic, assign, readonly) NSUInteger frameCacheSizeCurrent; // Current size of intelligently chosen buffer window; can range in the interval [1..frameCount]
@property (nonatomic, assign) NSUInteger frameCacheSizeMax; // Allow to cap the cache size; 0 means no specific limit (default)
// Intended to be called from main thread synchronously; will return immediately.
// If the result isn't cached, will return `nil`; the caller should then pause playback, not increment frame counter and keep polling.
// After an initial loading time, depending on `frameCacheSize`, frames should be available immediately from the cache.
- (UIImage *)imageLazilyCachedAtIndex:(NSUInteger)index;
// Pass either a `UIImage` or an `FLAnimatedImage` and get back its size
+ (CGSize)sizeForImage:(id)image;
// On success, the initializers return an `FLAnimatedImage` with all fields initialized, on failure they return `nil` and an error will be logged.
- (instancetype)initWithAnimatedGIFData:(NSData *)data;
// Pass 0 for optimalFrameCacheSize to get the default, predrawing is enabled by default.
- (instancetype)initWithAnimatedGIFData:(NSData *)data optimalFrameCacheSize:(NSUInteger)optimalFrameCacheSize predrawingEnabled:(BOOL)isPredrawingEnabled NS_DESIGNATED_INITIALIZER;
+ (instancetype)animatedImageWithGIFData:(NSData *)data;
@property (nonatomic, strong, readonly) NSData *data; // The data the receiver was initialized with; read-only
@end
@interface FLAnimatedImage (Logging)
+ (void)setLogBlock:(void (^)(NSString *logString, FLLogLevel logLevel))logBlock logLevel:(FLLogLevel)logLevel;
+ (void)logStringFromBlock:(NSString *(^)(void))stringBlock withLevel:(FLLogLevel)level;
@end
@interface FLWeakProxy : NSProxy
+ (instancetype)weakProxyForObject:(id)targetObject;
@end
可以看見贪嫂,這里面有三個接口寺庄。
2. FLAnimatedImageView.h
看一下接口
#import <UIKit/UIKit.h>
@class FLAnimatedImage;
@protocol FLAnimatedImageViewDebugDelegate;
//
// An `FLAnimatedImageView` can take an `FLAnimatedImage` and plays it automatically when in view hierarchy and stops when removed.
// The animation can also be controlled with the `UIImageView` methods `-start/stop/isAnimating`.
// It is a fully compatible `UIImageView` subclass and can be used as a drop-in component to work with existing code paths expecting to display a `UIImage`.
// Under the hood it uses a `CADisplayLink` for playback, which can be inspected with `currentFrame` & `currentFrameIndex`.
//
@interface FLAnimatedImageView : UIImageView
// Setting `[UIImageView.image]` to a non-`nil` value clears out existing `animatedImage`.
// And vice versa, setting `animatedImage` will initially populate the `[UIImageView.image]` to its `posterImage` and then start animating and hold `currentFrame`.
@property (nonatomic, strong) FLAnimatedImage *animatedImage;
@property (nonatomic, copy) void(^loopCompletionBlock)(NSUInteger loopCountRemaining);
@property (nonatomic, strong, readonly) UIImage *currentFrame;
@property (nonatomic, assign, readonly) NSUInteger currentFrameIndex;
// The animation runloop mode. Enables playback during scrolling by allowing timer events (i.e. animation) with NSRunLoopCommonModes.
// To keep scrolling smooth on single-core devices such as iPhone 3GS/4 and iPod Touch 4th gen, the default run loop mode is NSDefaultRunLoopMode. Otherwise, the default is NSDefaultRunLoopMode.
@property (nonatomic, copy) NSString *runLoopMode;
@end
框架使用
下面就看一下該框架的基本使用,給一個我自己寫的簡單示例力崇,直接看代碼斗塘。
#import "ViewController.h"
#import "FLAnimatedImageView.h"
#import "FLAnimatedImage.h"
@interface ViewController ()
@end
@implementation ViewController
#pragma mark - OVerride Base Function
- (void)viewDidLoad
{
[super viewDidLoad];
//找到路徑文件
NSString *pathStr = [[NSBundle mainBundle] pathForResource:@"gifAnimation.gif" ofType:nil];
//將gif轉化為NSData數(shù)據(jù)
NSData *gifData = [NSData dataWithContentsOfFile:pathStr];
//數(shù)據(jù)顯示
FLAnimatedImage *image = [FLAnimatedImage animatedImageWithGIFData:gifData];
FLAnimatedImageView *imageView = [[FLAnimatedImageView alloc] init];
imageView.animatedImage = image;
imageView.frame = CGRectMake(100.0, 200.0, 200.0, 200.0);
[self.view addSubview:imageView];
}
@end
下面看一下播放Gif圖的效果
這里只是一個簡單的使用,只是給大家簡單的展示亮靴。
后記
未完馍盟,待續(xù)~~~