背景
因为 .xcassets 中的图片资源只能通过 imageNamed:
方法加载,所以需要做一些特殊处理,才能提供给 weex 使用(PS:纯属娱乐,因为 weex 跨平台的特性,这种针对某一端做实现的方案实用价值并不大)。
方案
观察 WeexSDK 发现有 WXImgLoaderProtocol
这个协议,这个协议包含了下面的方法:
- (id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url imageFrame:(CGRect)imageFrame userInfo:(NSDictionary *)options completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock;
从名字就可以看出来,这个方法声明的功能就是通过指定的 URL 下载图片并返回一个 UIImage
对象。
下载过 WeexDemo 的人应该都知道里面有一个叫 WXImgLoaderDefaultImpl
的类(PS:别告诉我你对 weex 感兴趣确连 WeexDemo 里面有啥都不知道)。这个类实现了 WXImgLoaderProtocol
协议,内容如下:
- (id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url imageFrame:(CGRect)imageFrame userInfo:(NSDictionary *)userInfo completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock
{
if ([url hasPrefix:@"//"]) {
url = [@"http:" stringByAppendingString:url];
}
return (id<WXImageOperationProtocol>)[[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:url] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, finished);
}
}];
}
其实就是利用 SDWebImage
这个库实现图片下载功能。而且我还发现,如果不实现 WXImgLoaderProtocol
协议,就无法在 weex 的代码中通过 URL 加载网络图片。也就是说 weex 其实是依赖原生来做网络图片加载,至于为什么这么做,我只能说:我不知道。😂
然后 WeexDemo 通过下面的代码把 WXImgLoaderDefaultImpl
注册为 weex 的一个 iOS 原生 handler
[WXSDKEngine registerHandler:[WXImgLoaderDefaultImpl new] withProtocol:@protocol(WXImgLoaderProtocol)];
这样我们就可以在 weex 中加载网络图片了,比如:
<image class="img" style="width: 68px; height: 68px;margin-left:20px;" src="https://gw.alicdn.com/tps/TB1El.mKXXXXXXyapXXXXXXXXXX-34-34.gif"></image>
好了,现在就来说说怎么加载 .xcassets 中的图片资源,其实很简单,在 WXImgLoaderDefaultImpl
实现的方法中添加几行代码就可以:
if ([url hasPrefix:@"xcassets:"]) {
UIImage *image = [UIImage imageNamed:[url substringFromIndex:9]];
completedBlock(image, nil, YES);
return [WXXCassetsLoaderOperation new];
}
这里我定义的规则是:xcassets:+[.xcassets 中的图片名]。所以我们判断 url
是不是以 xcassets:
开头,如果是,通过 imageNamed
方法加载图片并返回即可。
因为 downloadImageWithURL
方法要求返回遵循 WXImageOperationProtocol
协议的对象,所以我们新建一个 WXXCassetsLoaderOperation
类,然后实现 WXImageOperationProtocol
协议中的 cancel
方法:
- (void)cancel {
}
然后我们就可以在 weex 中加载 .xcassets 中的图片了。代码如下:
<image class="img" style="width: 300px; height: 300px;" src="xcassets:reload"></image>
如有任何知识产权、版权问题或理论错误,还请指正。
转载请注明原作者及以上信息。