arrière-plan
Il est nécessaire d'utiliser les ressources CDN pour laisser Lottie faire des animations, mais comme les animations doivent charger des images, l'interface d'initialisation fournie par Lottie ne peut charger que des configurations json, et personne n'a répondu aux problèmes sur Github, j'ai donc écrit cet article pour enregistrer la solution.
Pour remplir cette fonction, j'ai même revu Lottie et j'étais ivre. . .
plan
Le premier point qui doit être précisé est que si votre ressource Lottie contient des images, l'utilisation directe de la méthode initWithContentsOfURL: de LOTAnimationView ne peut pas charger automatiquement la ressource image. Parce que le chargement des images doit définir baseURL pour LOTComposition, mais lors de l'initialisation animatonView via l'url, puisque la configuration json doit être chargée de manière asynchrone, le sceneModel de la vue est vide, vous ne pouvez pas le définir directement, et il n'y a pas de rappel pour l'achèvement du chargement à l'intérieur la vue, vous ne pouvez donc passer que les paramètres d'écoute de sceneModel ou générer un sceneModel à passer de ces deux manières pour réaliser le chargement des ressources d'image Lottie.
La mise en œuvre est décrite ci-dessous.
1. Ajouter l'agent LOTAnimationDelegate pour la bibliothèque Lottie
Tout d'abord, vous devez implémenter la méthode proxy de demande d'image de LOTAnimationView. Lottie ne demande pas d'images en interne et peut utiliser la méthode proxy dans la méthode _setImageForAsset: de LOTLayerContainer pour envoyer la demande d'image à l'extérieur pour l'implémentation. Récupérez ensuite l'image et attribuez-la à self.wrapperLayer.contents, l'exemple est le suivant.
- (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. Générer LOTComposition
Deuxièmement, étant donné que l'entreprise externe ne peut pas percevoir directement le moment de la LOTComposition générée à l'intérieur de la LTAAnimationView, elle peut choisir de la générer par elle-même et de définir la baseURL.
+ (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);
}
});
});
}
复制代码
Il convient de noter que le paramètre baseURL de LOTComposition doit non seulement afficher le fichier de configuration json de Lottie, mais doit également faire attention au chemin où le serveur stocke les fichiers Lottie.
假设你有一个叫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;
}
复制代码