Skip to content

Commit

Permalink
Added animation support & Added fade animation
Browse files Browse the repository at this point in the history
  • Loading branch information
geroale committed Mar 6, 2023
1 parent 1d13dcd commit 519dba7
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 94 deletions.
2 changes: 1 addition & 1 deletion ios/FastImage/FFFastImageView.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
@property (nonatomic, copy) RCTDirectEventBlock onFastImageLoad;
@property (nonatomic, copy) RCTDirectEventBlock onFastImageLoadEnd;
@property (nonatomic, assign) RCTResizeMode resizeMode;
@property (nonatomic, assign) NSString *animation;
@property (nonatomic, strong) FFFastImageSource *source;
@property (nonatomic, strong) UIImage *defaultSource;
@property (nonatomic, strong) UIColor *imageColor;

@end
Expand Down
185 changes: 93 additions & 92 deletions ios/FastImage/FFFastImageView.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
#import <SDWebImage/UIImage+MultiFormat.h>
#import <SDWebImage/UIView+WebCache.h>

@interface FFFastImageView ()
@interface FFFastImageView()

@property(nonatomic, assign) BOOL hasSentOnLoadStart;
@property(nonatomic, assign) BOOL hasCompleted;
@property(nonatomic, assign) BOOL hasErrored;
@property (nonatomic, assign) BOOL hasSentOnLoadStart;
@property (nonatomic, assign) BOOL hasCompleted;
@property (nonatomic, assign) BOOL hasErrored;
// Whether the latest change of props requires the image to be reloaded
@property(nonatomic, assign) BOOL needsReload;
@property (nonatomic, assign) BOOL needsReload;

@property(nonatomic, strong) NSDictionary* onLoadEvent;
@property (nonatomic, strong) NSDictionary* onLoadEvent;

@end

Expand All @@ -19,39 +19,48 @@ @implementation FFFastImageView
- (id) init {
self = [super init];
self.resizeMode = RCTResizeModeCover;
self.animation = @"none";
self.clipsToBounds = YES;
return self;
}

- (void) setResizeMode: (RCTResizeMode)resizeMode {
- (void)setResizeMode:(RCTResizeMode)resizeMode {
if (_resizeMode != resizeMode) {
_resizeMode = resizeMode;
self.contentMode = (UIViewContentMode) resizeMode;
self.contentMode = (UIViewContentMode)resizeMode;
}
}

- (void) setOnFastImageLoadEnd: (RCTDirectEventBlock)onFastImageLoadEnd {
- (void)setAnimation:(NSString*)animation {
if(_animation != animation) {
_animation = animation;
if([_animation isEqual: @"fade"])
self.sd_imageTransition = SDWebImageTransition.fadeTransition;
}
}

- (void)setOnFastImageLoadEnd:(RCTDirectEventBlock)onFastImageLoadEnd {
_onFastImageLoadEnd = onFastImageLoadEnd;
if (self.hasCompleted) {
_onFastImageLoadEnd(@{});
}
}

- (void) setOnFastImageLoad: (RCTDirectEventBlock)onFastImageLoad {
- (void)setOnFastImageLoad:(RCTDirectEventBlock)onFastImageLoad {
_onFastImageLoad = onFastImageLoad;
if (self.hasCompleted) {
_onFastImageLoad(self.onLoadEvent);
}
}

- (void) setOnFastImageError: (RCTDirectEventBlock)onFastImageError {
- (void)setOnFastImageError:(RCTDirectEventBlock)onFastImageError {
_onFastImageError = onFastImageError;
if (self.hasErrored) {
_onFastImageError(@{});
}
}

- (void) setOnFastImageLoadStart: (RCTDirectEventBlock)onFastImageLoadStart {
- (void)setOnFastImageLoadStart:(RCTDirectEventBlock)onFastImageLoadStart {
if (_source && !self.hasSentOnLoadStart) {
_onFastImageLoadStart = onFastImageLoadStart;
onFastImageLoadStart(@{});
Expand All @@ -62,106 +71,100 @@ - (void) setOnFastImageLoadStart: (RCTDirectEventBlock)onFastImageLoadStart {
}
}

- (void) setImageColor: (UIColor*)imageColor {
- (void)setImageColor:(UIColor *)imageColor {
if (imageColor != nil) {
_imageColor = imageColor;
if (super.image) {
super.image = [self makeImage: super.image withTint: self.imageColor];
}
super.image = [self makeImage:super.image withTint:self.imageColor];
}
}

- (UIImage*) makeImage: (UIImage*)image withTint: (UIColor*)color {
UIImage* newImage = [image imageWithRenderingMode: UIImageRenderingModeAlwaysTemplate];
- (UIImage*)makeImage:(UIImage *)image withTint:(UIColor *)color {
UIImage *newImage = [image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIGraphicsBeginImageContextWithOptions(image.size, NO, newImage.scale);
[color set];
[newImage drawInRect: CGRectMake(0, 0, image.size.width, newImage.size.height)];
[newImage drawInRect:CGRectMake(0, 0, image.size.width, newImage.size.height)];
newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}

- (void) setImage: (UIImage*)image {
- (void)setImage:(UIImage *)image {
if (self.imageColor != nil) {
super.image = [self makeImage: image withTint: self.imageColor];
super.image = [self makeImage:image withTint:self.imageColor];
} else {
super.image = image;
}
}

- (void) sendOnLoad: (UIImage*)image {
- (void)sendOnLoad:(UIImage *)image {
self.onLoadEvent = @{
@"width": [NSNumber numberWithDouble: image.size.width],
@"height": [NSNumber numberWithDouble: image.size.height]
};
@"width":[NSNumber numberWithDouble:image.size.width],
@"height":[NSNumber numberWithDouble:image.size.height]
};
if (self.onFastImageLoad) {
self.onFastImageLoad(self.onLoadEvent);
}
}

- (void) setSource: (FFFastImageSource*)source {
- (void)setSource:(FFFastImageSource *)source {
if (_source != source) {
_source = source;
_needsReload = YES;
}
}

- (void) setDefaultSource: (UIImage*)defaultSource {
if (_defaultSource != defaultSource) {
_defaultSource = defaultSource;
_needsReload = YES;
}
}

- (void) didSetProps: (NSArray<NSString*>*)changedProps {
- (void)didSetProps:(NSArray<NSString *> *)changedProps
{
if (_needsReload) {
[self reloadImage];
}
}

- (void) reloadImage {
- (void)reloadImage
{
_needsReload = NO;

if (_source) {

// Load base64 images.
NSString* url = [_source.url absoluteString];
if (url && [url hasPrefix: @"data:image"]) {
if (url && [url hasPrefix:@"data:image"]) {
if (self.onFastImageLoadStart) {
self.onFastImageLoadStart(@{});
self.hasSentOnLoadStart = YES;
} else {
} {
self.hasSentOnLoadStart = NO;
}
// Use SDWebImage API to support external format like WebP images
UIImage* image = [UIImage sd_imageWithData: [NSData dataWithContentsOfURL: _source.url]];
[self setImage: image];
UIImage *image = [UIImage sd_imageWithData:[NSData dataWithContentsOfURL:_source.url]];
[self setImage:image];
if (self.onFastImageProgress) {
self.onFastImageProgress(@{
@"loaded": @(1),
@"total": @(1)
});
@"loaded": @(1),
@"total": @(1)
});
}
self.hasCompleted = YES;
[self sendOnLoad: image];

[self sendOnLoad:image];
if (self.onFastImageLoadEnd) {
self.onFastImageLoadEnd(@{});
}
return;
}

// Set headers.
NSDictionary* headers = _source.headers;
SDWebImageDownloaderRequestModifier* requestModifier = [SDWebImageDownloaderRequestModifier requestModifierWithBlock: ^NSURLRequest* _Nullable (NSURLRequest* _Nonnull request) {
NSMutableURLRequest* mutableRequest = [request mutableCopy];
for (NSString* header in headers) {
NSString* value = headers[header];
[mutableRequest setValue: value forHTTPHeaderField: header];
NSDictionary *headers = _source.headers;
SDWebImageDownloaderRequestModifier *requestModifier = [SDWebImageDownloaderRequestModifier requestModifierWithBlock:^NSURLRequest * _Nullable(NSURLRequest * _Nonnull request) {
NSMutableURLRequest *mutableRequest = [request mutableCopy];
for (NSString *header in headers) {
NSString *value = headers[header];
[mutableRequest setValue:value forHTTPHeaderField:header];
}
return [mutableRequest copy];
}];
SDWebImageContext* context = @{SDWebImageContextDownloadRequestModifier: requestModifier};

SDWebImageContext *context = @{SDWebImageContextDownloadRequestModifier : requestModifier};
// Set priority.
SDWebImageOptions options = SDWebImageRetryFailed | SDWebImageHandleCookies;
switch (_source.priority) {
Expand All @@ -175,7 +178,7 @@ - (void) reloadImage {
options |= SDWebImageHighPriority;
break;
}

switch (_source.cacheControl) {
case FFFCacheControlWeb:
options |= SDWebImageRefreshCached;
Expand All @@ -186,58 +189,56 @@ - (void) reloadImage {
case FFFCacheControlImmutable:
break;
}

if (self.onFastImageLoadStart) {
self.onFastImageLoadStart(@{});
self.hasSentOnLoadStart = YES;
} else {
} {
self.hasSentOnLoadStart = NO;
}
self.hasCompleted = NO;
self.hasErrored = NO;

[self downloadImage: _source options: options context: context];
} else if (_defaultSource) {
[self setImage: _defaultSource];

[self downloadImage:_source options:options context:context];
}
}

- (void) downloadImage: (FFFastImageSource*)source options: (SDWebImageOptions)options context: (SDWebImageContext*)context {
- (void)downloadImage:(FFFastImageSource *) source options:(SDWebImageOptions) options context:(SDWebImageContext *)context {
__weak typeof(self) weakSelf = self; // Always use a weak reference to self in blocks
[self sd_setImageWithURL: _source.url
placeholderImage: _defaultSource
options: options
context: context
progress: ^(NSInteger receivedSize, NSInteger expectedSize, NSURL* _Nullable targetURL) {
[self sd_setImageWithURL:_source.url
placeholderImage:nil
options:options
context:context
progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
if (weakSelf.onFastImageProgress) {
weakSelf.onFastImageProgress(@{
@"loaded": @(receivedSize),
@"total": @(expectedSize)
});
@"loaded": @(receivedSize),
@"total": @(expectedSize)
});
}
} completed:^(UIImage * _Nullable image,
NSError * _Nullable error,
SDImageCacheType cacheType,
NSURL * _Nullable imageURL) {
if (error) {
weakSelf.hasErrored = YES;
if (weakSelf.onFastImageError) {
weakSelf.onFastImageError(@{});
}
if (weakSelf.onFastImageLoadEnd) {
weakSelf.onFastImageLoadEnd(@{});
}
} else {
weakSelf.hasCompleted = YES;
[weakSelf sendOnLoad:image];
if (weakSelf.onFastImageLoadEnd) {
weakSelf.onFastImageLoadEnd(@{});
}
}
} completed: ^(UIImage* _Nullable image,
NSError* _Nullable error,
SDImageCacheType cacheType,
NSURL* _Nullable imageURL) {
if (error) {
weakSelf.hasErrored = YES;
if (weakSelf.onFastImageError) {
weakSelf.onFastImageError(@{});
}
if (weakSelf.onFastImageLoadEnd) {
weakSelf.onFastImageLoadEnd(@{});
}
} else {
weakSelf.hasCompleted = YES;
[weakSelf sendOnLoad: image];
if (weakSelf.onFastImageLoadEnd) {
weakSelf.onFastImageLoadEnd(@{});
}
}
}];
}

- (void) dealloc {
}];
}

- (void)dealloc {
[self sd_cancelCurrentImageLoad];
}

Expand Down
2 changes: 1 addition & 1 deletion ios/FastImage/FFFastImageViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ - (FFFastImageView*)view {
}

RCT_EXPORT_VIEW_PROPERTY(source, FFFastImageSource)
RCT_EXPORT_VIEW_PROPERTY(defaultSource, UIImage)
RCT_EXPORT_VIEW_PROPERTY(resizeMode, RCTResizeMode)
RCT_EXPORT_VIEW_PROPERTY(animation, NSString)
RCT_EXPORT_VIEW_PROPERTY(onFastImageLoadStart, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onFastImageProgress, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onFastImageError, RCTDirectEventBlock)
Expand Down

0 comments on commit 519dba7

Please sign in to comment.