Hintergrund
Es ist notwendig, CDN-Ressourcen zu verwenden, um Lottie Animationen ausführen zu lassen, aber da Animationen Bilder laden müssen, kann die von Lottie bereitgestellte Initialisierungsschnittstelle nur json-Konfigurationen laden, und niemand hat die Probleme auf Github beantwortet, also habe ich diesen Artikel geschrieben Notieren Sie die Lösung.
Um diese Funktion zu erreichen, habe ich sogar noch einmal Lottie angeschaut und war betrunken. . .
planen
Der erste Punkt, der klargestellt werden muss, ist, dass, wenn Ihre Lottie-Ressource Bilder enthält, die Bildressource nicht automatisch durch direktes Verwenden der Methode initWithContentsOfURL: von LOTAnimationView geladen werden kann. Da beim Laden von Bildern baseURL für LOTComposition festgelegt werden muss, aber beim Initialisieren von animatonView über die URL, da die json-Konfiguration asynchron geladen werden muss, das sceneModel der Ansicht leer ist, können Sie es nicht direkt festlegen, und es gibt keinen Callback für den Abschluss des Ladevorgangs im Inneren die Ansicht, sodass Sie nur Listen to sceneModel-Einstellungen übergeben oder ein sceneModel generieren können, um diese beiden Möglichkeiten zu übergeben, um das Laden von Lottie-Bildressourcen zu realisieren.
Die Implementierung wird unten beschrieben.
1. Fügen Sie den LOTAnimationDelegate-Agenten für die Lottie-Bibliothek hinzu
Zuerst müssen Sie die Bildanforderungs-Proxy-Methode von LOTAnimationView implementieren. Lottie fordert intern keine Bilder an und kann die Proxy-Methode in der _setImageForAsset:-Methode von LOTLayerContainer verwenden, um die Bildanforderung zur Implementierung nach außen zu werfen. Holen Sie sich dann das Bild und weisen Sie es self.wrapperLayer.contents zu, das Beispiel ist wie folgt.
- (void)_setImageForAsset:(LOTAsset *)asset {
...
[delegate animationView:asset.animationView fetchResourceWithURL:url completionHandler:^(UIImage * _Nullable image, NSError * _Nullable error) {
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
self.wrapperLayer.contents = (__bridge id _Nullable)(image.CGImage);
});
}
}];
...
}
- (void)animationView:(LOTAnimationView *)animationView fetchResourceWithURL:(NSURL *)url completionHandler:(LOTResourceCompletionHandler)completionHandler {
[CDNService requestLottieImageWithURL:url completion:^(UIImage * _Nullable image, NSError * _Nullable error) {
if (completionHandler) {
completionHandler(image, error);
}
}];
}
复制代码
2. Generieren Sie LOTComposition
Zweitens kann das externe Unternehmen, da es das Timing der in LOTAnimationView generierten LOTComposition nicht direkt wahrnehmen kann, es selbst generieren und die Basis-URL festlegen.
+ (void)requestLottieModelWithURL:(NSURL *)url completion:(void(^)(LOTComposition * _Nullable sceneModel, NSError * _Nullable error))completion {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
NSData *animationData = [NSData dataWithContentsOfURL:url];
if (!animationData) {
return;
}
NSError *error;
NSDictionary *animationJSON = [NSJSONSerialization JSONObjectWithData:animationData options:0 error:&error];
if (error || !animationJSON) {
if (completion) {
completion(nil, error);
}
return;
}
LOTComposition *model = [[LOTComposition alloc] initWithJSON:animationJSON withAssetBundle:[NSBundle mainBundle]];
dispatch_async(dispatch_get_main_queue(), ^(void) {
[[LOTAnimationCache sharedCache] addAnimation:model forKey:url.absoluteString];
//注意,这里的baseURL是你的请求path,需要根据你的业务情况自行设置
model.baseURL = @"https://os.xxx.cn/lottie/animation/";
model.cacheKey = url.absoluteString;
if (completion) {
completion(model, nil);
}
});
});
}
复制代码
Es sollte beachtet werden, dass die baseURL-Einstellung von LOTComposition nicht nur die json-Konfigurationsdatei von Lottie anzeigen muss, sondern auch den Pfad beachten muss, in dem der Server Lottie-Dateien speichert.
假设你有一个叫animation的Lottie资源,那么请先打开配置json观察assets.u的值。这里假设assets.u为"images/",则你需要在服务端存储的文件结构如下:
- animation
- data.json
- images
- img_0.png
- img_1.png
复制代码
此时,如果json的请求url是https://os.xxx.cn/lottie/animation/data.json
,那么需要给LOTComposition的baseURL设置为https://os.xxx.cn/lottie/animation/
。
3. 初始化LOTAnimationView
最后只需要请求资源并传给LOTAnimationView即可。
- (LOTAnimationView *)animationView {
if (!_animationView) {
//注意,如果想先初始化view再请求资源,不要使用new或者init来初始化
_animationView = [[LOTAnimationView alloc] initWithFrame:CGRectZero];
_animationView.animationDelegate = self;
NSURL *url = [NSURL URLWithString:@"https://os.xxx.cn/lottie/animation/data.json"];
//请求json配置,生成LOTComposition后传给view
@weakify(self);
[CCDNService requestLottieModelWithURL:url completion:^(LOTComposition * _Nullable sceneModel, NSError * _Nullable error) {
@strongify(self);
self.animationView.sceneModel = sceneModel;
}];
}
return _animationView;
}
复制代码