<image>
组件用于渲染图片,并且它不能包含任何子组件。可以用<img>
作简写。需要注意的是,需要明确指定
width
和height
,否则图片无法显示。<image>
组件不支持任何子组件,
特性
-
src {string}
:定义图片链接,目前图片暂不支持本地图片。 -
resize {string}
:可以控制图片的拉伸状态,值行为和 W3C 标准一致。
可选值为:
stretch
:默认值,指定图片按照容器拉伸,有可能使图片产生形变。
cover
:指定图片可以被调整到容器,以使图片完全覆盖背景区域,图片有可能被剪裁。
contain
:指定可以不用考虑容器的大小,把图像扩展至最大尺寸,以使其宽度和高度完全适应内容区域。 -
placeholder: <string>
当源图片下载中时显示一张占位图。
事件
-
load:
当图片加载完成时触发。
示例
<template>
<scroller class="wrapper" >
<div class="page-head" >
<image class="title-bg" resize="cover" src="https://img.alicdn.com/tps/TB1dX5NOFXXXXc6XFXXXXXXXXXX-750-202.png"></image>
<div class="title-box">
<text class="title">Alan Mathison Turing</text>
</div>
</div>
<div class="article">
<text class="paragraph">Alan Mathison Turing ( 23 June 1912 – 7 June 1954) was an English computer scientist, mathematician, logician, cryptanalyst and theoretical biologist. He was highly influential in the development of theoretical computer science, providing a formalisation of the concepts of algorithm and computation with the Turing machine, which can be considered a model of a general purpose computer.Turing is widely considered to be the father of theoretical computer science and artificial intelligence.</text>
<text class="paragraph">During the Second World War, Turing worked for the Government Code and Cypher School (GC&CS) at Bletchley Park, Britain's codebreaking centre. For a time he led Hut 8, the section responsible for German naval cryptanalysis. He devised a number of techniques for speeding the breaking of German ciphers, including improvements to the pre-war Polish bombe method, an electromechanical machine that could find settings for the Enigma machine. Turing played a pivotal role in cracking intercepted coded messages that enabled the Allies to defeat the Nazis in many crucial engagements, including the Battle of the Atlantic; it has been estimated that this work shortened the war in Europe by more than two years and saved over fourteen million lives.</text>
<text class="paragraph">After the war, he worked at the National Physical Laboratory, where he designed the ACE, among the first designs for a stored-program computer. In 1948 Turing joined Max Newman's Computing Machine Laboratory at the Victoria University of Manchester, where he helped develop the Manchester computers and became interested in mathematical biology. He wrote a paper on the chemical basis of morphogenesis, and predicted oscillating chemical reactions such as the Belousov–Zhabotinsky reaction, first observed in the 1960s.</text>
<text class="paragraph">Turing was prosecuted in 1952 for homosexual acts, when by the Labouchere Amendment, "gross indecency" was still criminal in the UK. He accepted chemical castration treatment, with DES, as an alternative to prison. Turing died in 1954, 16 days before his 42nd birthday, from cyanide poisoning. An inquest determined his death as suicide, but it has been noted that the known evidence is also consistent with accidental poisoning. In 2009, following an Internet campaign, British Prime Minister Gordon Brown made an official public apology on behalf of the British government for "the appalling way he was treated." Queen Elizabeth II granted him a posthumous pardon in 2013.</text>
</div>
</scroller>
</template>
<style>
.page-head {
width: 750px;
height: 200px;
}
.title-bg {
width: 750px;
height: 200px;
}
.title-box {
width: 750px;
height: 200px;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.title {
color: #ffffff;
font-size: 32px;
font-weight: bold;
}
.article {
padding: 20px;
}
.paragraph{
margin-bottom: 15px;
}
</style>
SDK 源码
- 组件类:
WXImageComponent
[self registerComponent:@"image" withClass:NSClassFromString(@"WXImageComponent") withProperties:nil];
- 用UIImageView来实现
@interface WXImageView : UIImageView
@end
- (UIView *)loadView
{
return [[WXImageView alloc] init];
}
- (void)viewDidLoad
{
UIImageView *imageView = (UIImageView *)self.view;
imageView.contentMode = _resizeMode;
imageView.userInteractionEnabled = YES;
imageView.clipsToBounds = YES;
imageView.exclusiveTouch = YES;
[self updateImage];
}
- 关于图片图片模式,由
resize
参数传入,转化为UIViewContentMode
进行设置
if (attributes[@"resize"]) {
_resizeMode = [WXConvert UIViewContentMode:attributes[@"resize"]];
self.view.contentMode = _resizeMode;
}
+ (UIViewContentMode)UIViewContentMode:(id)value
{
if([value isKindOfClass:[NSString class]]){
NSString *string = (NSString *)value;
if ([string isEqualToString:@"cover"])
return UIViewContentModeScaleAspectFill;
else if ([string isEqualToString:@"contain"])
return UIViewContentModeScaleAspectFit;
else if ([string isEqualToString:@"stretch"])
return UIViewContentModeScaleToFill;
}
return UIViewContentModeScaleToFill;
}
-
placeHolder
和src
参数应该都是url,两者在实现上差不多,placeholder
也是兼容的。
@property (nonatomic, strong) NSString *imageSrc;
@property (nonatomic, strong) NSString *placeholdSrc;
@property (nonatomic, strong) id<WXImageOperationProtocol> imageOperation;
@property (nonatomic, strong) id<WXImageOperationProtocol> placeholderOperation;
if (attributes[@"src"]) {
_imageSrc = [[WXConvert NSString:attributes[@"src"]] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
if (attributes[@"placeHolder"] || attributes[@"placeholder"]) {
_placeholdSrc = [[WXConvert NSString:attributes[@"placeHolder"]?attributes[@"placeHolder"]:attributes[@"placeholder"]]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- 取消下载:虽然cancel的方法可能没实现,不过操作会被设置为nil,下载进程会被强制取消
- (void)cancelImage
{
[_imageOperation cancel];
_imageOperation = nil;
[_placeholderOperation cancel];
_placeholderOperation = nil;
}
-
imageSharp
和imageQuality
可以传入,是给下载协议的实现函数用的。目前一般的实现函数都不会去用,所以暂时这两个参数不用管
NSDictionary *userInfo = @{@"imageQuality":@(weakSelf.imageQuality), @"imageSharp":@(weakSelf.imageSharp)};
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.imageOperation = [[weakSelf imageLoader] downloadImageWithURL:imageSrc imageFrame:weakSelf.calculatedFrame userInfo:userInfo completed:^(UIImage *image, NSError *error, BOOL finished) {
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(self) strongSelf = weakSelf;
if (weakSelf.imageLoadEvent) {
[strongSelf fireEvent:@"load" params:@{ @"success": error? @"false" : @"true"}];
}
if (error) {
downloadFailed(imageSrc, error);
return ;
}
if (![imageSrc isEqualToString:strongSelf.imageSrc]) {
return ;
}
if ([strongSelf isViewLoaded]) {
((UIImageView *)strongSelf.view).image = image;
}
});
}];
});
不足之处
既然可以自定义组件,不如参考他的写法,写一个自定义的image组件,可能更好用一点
- 下载函数通过一个协议去实现,绕了一大圈,没什么必要;当然从框架层面提高扩展性还是可以的。自定义的组件就没有必要了。
- 下载过程放在了一个全局的串行队列之中,中间又通过GCD套了好几层的主线程。真正的下载过程,实现者一般是会另外开并行队列去做得,这里的串行队列只是去分发下载任务。所以这种做法纯粹将简单任务复杂化,有点啰嗦。比如我们用SDWebImage来实现下载过程,下面是模拟的代码
#import "ViewController.h"
static dispatch_queue_t WXImageUpdateQueue;
static NSOperationQueue *operationQueue;
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
WXImageUpdateQueue = dispatch_queue_create("com.taobao.weex.ImageUpdateQueue", DISPATCH_QUEUE_SERIAL);
operationQueue = [[NSOperationQueue alloc] init];
operationQueue.maxConcurrentOperationCount = 3;
for (NSInteger i = 0; i < 5; i++) {
[self updateImage:(i + 1)];
}
}
- (void)updateImage:(NSInteger)index {
dispatch_async(WXImageUpdateQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
[operationQueue addOperationWithBlock:^{
NSTimeInterval ti = 0;
if ((1 == index) || (3 == index)) {
ti = 1.0;
} else if ((2 == index) || (4 == index)) {
ti = 0.5;
} else {
ti = 0.2;
}
[NSThread sleepForTimeInterval:ti];
NSLog(@"image %ld finished", (long)index);
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"image %ld displayed", (long)index);
});
}];
});
});
}
@end
-
placeHolder
也要远程下载,这个有点无语,这个除了增加网络负担,还有什么价值? - 实现一个本地图片加载不是比网络去图片更简单吗?为什么不实现?不理解这样做的原因。所以,还是自己写一个图片组件比较好,框架提供的,真的不好用。