mirror of
https://github.com/Tencent/Hippy.git
synced 2026-10-28 21:48:13 +08:00
fix(ios): cancel previous custom image loading when a new request come
This commit is contained in:
@@ -131,6 +131,7 @@ UIImage *HippyBlurredImageWithRadiusv(UIImage *inputImage, CGFloat radius)
|
||||
|
||||
@interface HippyImageView () {
|
||||
NSURLSessionDataTask *_task;
|
||||
NSURL *_imageLoadURL;
|
||||
long long _totalLength;
|
||||
NSMutableData *_data;
|
||||
__weak CALayer *_borderWidthLayer;
|
||||
@@ -267,10 +268,10 @@ UIImage *HippyBlurredImageWithRadiusv(UIImage *inputImage, CGFloat radius)
|
||||
- (void)reloadImage
|
||||
{
|
||||
NSDictionary *source = [self.source firstObject];
|
||||
if (source && CGRectGetWidth(self.frame) > 0 && CGRectGetHeight(self.frame) > 0) {
|
||||
if (_onLoadStart) {
|
||||
_onLoadStart(@{});
|
||||
}
|
||||
if (source && CGRectGetWidth(self.frame) > 0 && CGRectGetHeight(self.frame) > 0) {
|
||||
if (_onLoadStart) {
|
||||
_onLoadStart(@{});
|
||||
}
|
||||
NSString *uri = source[@"uri"];
|
||||
|
||||
BOOL isBlurredImage = NO;
|
||||
@@ -291,7 +292,7 @@ UIImage *HippyBlurredImageWithRadiusv(UIImage *inputImage, CGFloat radius)
|
||||
BOOL fileExist = [[NSFileManager defaultManager] fileExistsAtPath:localPath isDirectory:&isDirectory];
|
||||
if (fileExist && !isDirectory) {
|
||||
NSData *imageData = [NSData dataWithContentsOfFile:localPath];
|
||||
Class<HippyImageProviderProtocol> ipClass = imageProviderClassFromBridge(imageData, _bridge);
|
||||
Class<HippyImageProviderProtocol> ipClass = imageProviderClassFromBridge(imageData, self.bridge);
|
||||
id<HippyImageProviderProtocol> instance = [self instanceImageProviderFromClass:ipClass imageData:imageData];
|
||||
BOOL isAnimatedImage = [ipClass isAnimatedImage:imageData];
|
||||
if (isAnimatedImage) {
|
||||
@@ -312,19 +313,45 @@ UIImage *HippyBlurredImageWithRadiusv(UIImage *inputImage, CGFloat radius)
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(_bridge.imageLoader && source_url) {
|
||||
if (_defaultImage) {
|
||||
self.image = _defaultImage;
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
||||
typedef void (^HandleBase64CompletedBlock)(NSString *);
|
||||
HandleBase64CompletedBlock handleBase64CompletedBlock = ^void(NSString *base64Data) {
|
||||
NSRange range = [base64Data rangeOfString:@";base64,"];
|
||||
if (NSNotFound != range.location) {
|
||||
base64Data = [base64Data substringFromIndex:range.location + range.length];
|
||||
NSData *imageData = [[NSData alloc] initWithBase64EncodedString:base64Data
|
||||
options: NSDataBase64DecodingIgnoreUnknownCharacters];
|
||||
Class<HippyImageProviderProtocol> ipClass = imageProviderClassFromBridge(imageData, self.bridge);
|
||||
id<HippyImageProviderProtocol> instance = [self instanceImageProviderFromClass:ipClass imageData:imageData];
|
||||
BOOL isAnimatedImage = [ipClass isAnimatedImage:imageData];
|
||||
if (isAnimatedImage) {
|
||||
if (weakSelf.animatedImageOperation) {
|
||||
[weakSelf.animatedImageOperation cancel];
|
||||
}
|
||||
weakSelf.animatedImageOperation = [[HippyAnimatedImageOperation alloc] initWithAnimatedImageProvider:instance imageView:self imageURL:source[@"uri"]];
|
||||
[animated_image_queue() addOperation:weakSelf.animatedImageOperation];
|
||||
}
|
||||
else {
|
||||
UIImage *image = [instance image];
|
||||
NSError *error = nil;
|
||||
if (!image) {
|
||||
error = [NSError errorWithDomain: NSURLErrorDomain code: -1 userInfo: @{NSLocalizedDescriptionKey: @"base64 url is invalidated"}];
|
||||
}
|
||||
[weakSelf loadImage: image url: source[@"uri"] error: error needBlur:YES needCache:YES];
|
||||
}
|
||||
}
|
||||
__weak __typeof(self) weakSelf = self;
|
||||
[_bridge.imageLoader imageView:weakSelf loadAtUrl:source_url placeholderImage:_defaultImage context: NULL progress:^(long long currentLength, long long totalLength) {
|
||||
__typeof(weakSelf) strongSelf = weakSelf;
|
||||
if (strongSelf.onProgress) {
|
||||
strongSelf.onProgress(@{@"loaded": @((double)currentLength), @"total": @((double)totalLength)});
|
||||
}
|
||||
} completed:^(NSData *data, NSURL *url, NSError *error) {
|
||||
__typeof(weakSelf) strongSelf = weakSelf;
|
||||
Class<HippyImageProviderProtocol> ipClass = imageProviderClassFromBridge(data, strongSelf.bridge);
|
||||
};
|
||||
|
||||
typedef void(^HandleImageCompletedBlock)(NSURL *);
|
||||
HandleImageCompletedBlock handleImageCompletedBlock = ^void(NSURL *source_url) {
|
||||
[weakSelf.bridge.imageLoader imageView:weakSelf loadAtUrl:source_url placeholderImage:weakSelf.defaultImage context: NULL progress:^(long long currentLength, long long totalLength) {
|
||||
if (weakSelf.onProgress) {
|
||||
weakSelf.onProgress(@{@"loaded": @((double)currentLength), @"total": @((double)totalLength)});
|
||||
}
|
||||
} completed:^(NSData *data, NSURL *url, NSError *error) {
|
||||
Class<HippyImageProviderProtocol> ipClass = imageProviderClassFromBridge(data, self.bridge);
|
||||
id<HippyImageProviderProtocol> instance = [self instanceImageProviderFromClass:ipClass imageData:data];
|
||||
BOOL isAnimatedImage = [ipClass isAnimatedImage:data];
|
||||
if (isAnimatedImage) {
|
||||
@@ -334,38 +361,36 @@ UIImage *HippyBlurredImageWithRadiusv(UIImage *inputImage, CGFloat radius)
|
||||
weakSelf.animatedImageOperation = [[HippyAnimatedImageOperation alloc] initWithAnimatedImageProvider:instance imageView:self imageURL:source[@"uri"]];
|
||||
[animated_image_queue() addOperation:weakSelf.animatedImageOperation];
|
||||
}
|
||||
else {
|
||||
UIImage *image = [instance image];
|
||||
[weakSelf loadImage: image url: url.absoluteString error: error needBlur:YES needCache:YES];
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
if ([uri hasPrefix: @"data:image/"]) {
|
||||
NSString *base64Data = uri;
|
||||
NSRange range = [uri rangeOfString:@";base64,"];
|
||||
if (NSNotFound != range.location) {
|
||||
base64Data = [uri substringFromIndex:range.location + range.length];
|
||||
}
|
||||
NSData *imageData = [[NSData alloc] initWithBase64EncodedString:base64Data options: NSDataBase64DecodingIgnoreUnknownCharacters];
|
||||
Class<HippyImageProviderProtocol> ipClass = imageProviderClassFromBridge(imageData, self.bridge);
|
||||
id<HippyImageProviderProtocol> instance = [self instanceImageProviderFromClass:ipClass imageData:imageData];
|
||||
BOOL isAnimatedImage = [ipClass isAnimatedImage:imageData];
|
||||
if (isAnimatedImage) {
|
||||
if (_animatedImageOperation) {
|
||||
[_animatedImageOperation cancel];
|
||||
}
|
||||
_animatedImageOperation = [[HippyAnimatedImageOperation alloc] initWithAnimatedImageProvider:instance imageView:self imageURL:source[@"uri"]];
|
||||
[animated_image_queue() addOperation:_animatedImageOperation];
|
||||
}
|
||||
else {
|
||||
UIImage *image = [instance image];
|
||||
NSError *error = nil;
|
||||
if (!image) {
|
||||
error = [NSError errorWithDomain: NSURLErrorDomain code: -1 userInfo: @{NSLocalizedDescriptionKey: @"base64 url is invalidated"}];
|
||||
}
|
||||
[self loadImage: image url: source[@"uri"] error: error needBlur:YES needCache:YES];
|
||||
[weakSelf loadImage: image url: source[@"uri"] error: error needBlur:YES needCache:YES];
|
||||
}
|
||||
}
|
||||
}];
|
||||
};
|
||||
|
||||
if(_bridge.imageLoader && source_url) {
|
||||
if (_defaultImage) {
|
||||
weakSelf.image = _defaultImage;
|
||||
}
|
||||
|
||||
if ([[source_url absoluteString] hasPrefix: @"data:image/"]) {
|
||||
handleBase64CompletedBlock([source_url absoluteString]);
|
||||
} else {
|
||||
if (_imageLoadURL) {
|
||||
[_bridge.imageLoader cancelImageDownload:self withUrl:_imageLoadURL];
|
||||
}
|
||||
_imageLoadURL = source_url;
|
||||
handleImageCompletedBlock(source_url);
|
||||
}
|
||||
|
||||
} else {
|
||||
if ([uri hasPrefix: @"data:image/"]) {
|
||||
handleBase64CompletedBlock(uri);
|
||||
}
|
||||
else {
|
||||
if (_task) {
|
||||
[self cancelImageLoad];
|
||||
@@ -375,8 +400,8 @@ UIImage *HippyBlurredImageWithRadiusv(UIImage *inputImage, CGFloat radius)
|
||||
_task = [session dataTaskWithURL:source_url];
|
||||
[_task resume];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)cancelImageLoad
|
||||
@@ -558,7 +583,7 @@ UIImage *HippyBlurredImageWithRadiusv(UIImage *inputImage, CGFloat radius)
|
||||
// self.layer.magnificationFilter = kCAFilterTrilinear;
|
||||
|
||||
if (image.images) {
|
||||
HippyAssert(NO, @"GIF图片不应该进入这个逻辑");
|
||||
HippyAssert(NO, @"GIF should not invoke this");
|
||||
}
|
||||
else {
|
||||
self.image = image;
|
||||
|
||||
Reference in New Issue
Block a user