添加图片库、封装
This commit is contained in:
31
keyBoard/Class/Categories/KBWebImageManager.h
Normal file
31
keyBoard/Class/Categories/KBWebImageManager.h
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// KBWebImageManager.h
|
||||
// keyBoard
|
||||
//
|
||||
// SDWebImage 的二次封装:全局配置、预取、缓存管理
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface KBWebImageManager : NSObject
|
||||
|
||||
/// 预取一组图片
|
||||
+ (void)prefetchURLs:(NSArray<id> *)urlList
|
||||
progress:(void(^_Nullable)(NSUInteger finished, NSUInteger total))progress
|
||||
completed:(void(^_Nullable)(NSUInteger finished, NSUInteger skipped))completed;
|
||||
|
||||
/// 异步计算磁盘缓存大小(字节)
|
||||
+ (void)calculateDiskSize:(void(^)(NSUInteger bytes))completion;
|
||||
|
||||
/// 清理内存+磁盘缓存
|
||||
+ (void)clearAllCache:(void(^_Nullable)(void))completion;
|
||||
|
||||
/// 设置全局 HTTP Header(如鉴权 Token)
|
||||
+ (void)setHTTPHeaderValue:(nullable NSString *)value forKey:(NSString *)field;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
51
keyBoard/Class/Categories/KBWebImageManager.m
Normal file
51
keyBoard/Class/Categories/KBWebImageManager.m
Normal file
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// KBWebImageManager.m
|
||||
// keyBoard
|
||||
//
|
||||
|
||||
#import "KBWebImageManager.h"
|
||||
#import <SDWebImage/SDWebImage.h>
|
||||
|
||||
static inline NSURL *_KBURL(id url) {
|
||||
if (!url) return nil;
|
||||
if ([url isKindOfClass:NSURL.class]) return url;
|
||||
if ([url isKindOfClass:NSString.class]) return [NSURL URLWithString:(NSString *)url];
|
||||
return nil;
|
||||
}
|
||||
|
||||
@implementation KBWebImageManager
|
||||
|
||||
+ (void)prefetchURLs:(NSArray<id> *)urlList
|
||||
progress:(void(^)(NSUInteger finished, NSUInteger total))progress
|
||||
completed:(void(^)(NSUInteger finished, NSUInteger skipped))completed {
|
||||
NSMutableArray<NSURL *> *urls = [NSMutableArray arrayWithCapacity:urlList.count];
|
||||
for (id u in urlList) { NSURL *nu = _KBURL(u); if (nu) [urls addObject:nu]; }
|
||||
[[SDWebImagePrefetcher sharedImagePrefetcher] prefetchURLs:urls progress:^(NSUInteger noOfFinishedUrls, NSUInteger noOfTotalUrls) {
|
||||
if (progress) progress(noOfFinishedUrls, noOfTotalUrls);
|
||||
} completed:^(NSUInteger finishedCount, NSUInteger skippedCount) {
|
||||
if (completed) completed(finishedCount, skippedCount);
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void)calculateDiskSize:(void(^)(NSUInteger bytes))completion {
|
||||
[[SDImageCache sharedImageCache] calculateSizeWithCompletionBlock:^(NSUInteger fileCount, NSUInteger totalSize) {
|
||||
if (completion) completion(totalSize);
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void)clearAllCache:(void(^)(void))completion {
|
||||
SDImageCache *cache = SDImageCache.sharedImageCache;
|
||||
[cache clearMemory];
|
||||
[cache clearDiskOnCompletion:^{ if (completion) completion(); }];
|
||||
}
|
||||
|
||||
+ (void)setHTTPHeaderValue:(NSString *)value forKey:(NSString *)field {
|
||||
if (value.length == 0) {
|
||||
[[SDWebImageDownloader sharedDownloader] setValue:nil forHTTPHeaderField:field];
|
||||
} else {
|
||||
[[SDWebImageDownloader sharedDownloader] setValue:value forHTTPHeaderField:field];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
49
keyBoard/Class/Categories/UIImageView+KBWebImage.h
Normal file
49
keyBoard/Class/Categories/UIImageView+KBWebImage.h
Normal file
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// UIImageView+KBWebImage.h
|
||||
// keyBoard
|
||||
//
|
||||
// 在 SDWebImage 基础上的便捷封装:
|
||||
// - 统一默认 options(失败重试、后台续传、降采样等)
|
||||
// - 支持按视图大小缩略解码,减少内存占用
|
||||
// - 常用形状:普通、圆角、头像圆形
|
||||
// - 支持占位图、渐隐动画、取消下载
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface UIImageView (KBWebImage)
|
||||
|
||||
/// 简单加载(默认 options,自动渐隐)
|
||||
- (void)kb_setImageURL:(nullable id)url placeholder:(nullable UIImage *)placeholder;
|
||||
|
||||
/// 自定义 options
|
||||
- (void)kb_setImageURL:(nullable id)url
|
||||
placeholder:(nullable UIImage *)placeholder
|
||||
options:(NSUInteger)options;
|
||||
|
||||
/// 按视图大小缩略解码(推荐:内存友好)。若视图尚未布局,可传入 `targetSize` 期望像素尺寸(点×scale)。
|
||||
- (void)kb_setImageURL:(nullable id)url
|
||||
placeholder:(nullable UIImage *)placeholder
|
||||
thumbnailToFit:(BOOL)thumbnailToFit
|
||||
targetSize:(CGSize)targetPixelSize;
|
||||
|
||||
/// 圆角图(在解码阶段裁圆角,避免离屏开销)
|
||||
- (void)kb_setImageURL:(nullable id)url
|
||||
placeholder:(nullable UIImage *)placeholder
|
||||
cornerRadius:(CGFloat)radius
|
||||
corners:(UIRectCorner)corners
|
||||
borderWidth:(CGFloat)borderWidth
|
||||
borderColor:(nullable UIColor *)borderColor;
|
||||
|
||||
/// 头像:自动按最短边裁成圆形(若视图尚未布局,会使用当前 bounds 估算)
|
||||
- (void)kb_setAvatarURL:(nullable id)url placeholder:(nullable UIImage *)placeholder;
|
||||
|
||||
/// 取消当前图的下载
|
||||
- (void)kb_cancelImageLoad;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
142
keyBoard/Class/Categories/UIImageView+KBWebImage.m
Normal file
142
keyBoard/Class/Categories/UIImageView+KBWebImage.m
Normal file
@@ -0,0 +1,142 @@
|
||||
//
|
||||
// UIImageView+KBWebImage.m
|
||||
// keyBoard
|
||||
//
|
||||
|
||||
#import "UIImageView+KBWebImage.h"
|
||||
#import <SDWebImage/SDWebImage.h>
|
||||
|
||||
// 默认下载配置:失败重试、后台续传、降采样、大图优先级
|
||||
static inline SDWebImageOptions KBWebImageDefaultOptions(void) {
|
||||
return SDWebImageRetryFailed |
|
||||
SDWebImageContinueInBackground |
|
||||
SDWebImageHighPriority |
|
||||
SDWebImageScaleDownLargeImages |
|
||||
SDWebImageProgressiveLoad; // 渐进式
|
||||
}
|
||||
|
||||
static inline NSURL *_KBURL(id url) {
|
||||
if (!url) return nil;
|
||||
if ([url isKindOfClass:NSURL.class]) return url;
|
||||
if ([url isKindOfClass:NSString.class]) return [NSURL URLWithString:(NSString *)url];
|
||||
return nil;
|
||||
}
|
||||
|
||||
@implementation UIImageView (KBWebImage)
|
||||
|
||||
- (void)kb_setImageURL:(id)url placeholder:(UIImage *)placeholder {
|
||||
[self kb_setImageURL:url placeholder:placeholder options:KBWebImageDefaultOptions()];
|
||||
}
|
||||
|
||||
- (void)kb_setImageURL:(id)url placeholder:(UIImage *)placeholder options:(NSUInteger)options {
|
||||
NSURL *u = _KBURL(url);
|
||||
// 默认渐隐动画
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[self sd_setImageWithURL:u
|
||||
placeholderImage:placeholder
|
||||
options:options
|
||||
progress:nil
|
||||
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
||||
if (!error && image && cacheType == SDImageCacheTypeNone) {
|
||||
// 网络新图,做一次淡入动画
|
||||
weakSelf.alpha = 0.0;
|
||||
[UIView animateWithDuration:0.25 animations:^{ weakSelf.alpha = 1.0; }];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)kb_setImageURL:(id)url
|
||||
placeholder:(UIImage *)placeholder
|
||||
thumbnailToFit:(BOOL)thumbnailToFit
|
||||
targetSize:(CGSize)targetPixelSize {
|
||||
NSURL *u = _KBURL(url);
|
||||
SDWebImageOptions options = KBWebImageDefaultOptions();
|
||||
NSMutableDictionary<SDWebImageContextOption, id> *context = [NSMutableDictionary dictionary];
|
||||
|
||||
if (thumbnailToFit) {
|
||||
CGFloat scale = UIScreen.mainScreen.scale;
|
||||
CGSize size = self.bounds.size;
|
||||
if (CGSizeEqualToSize(size, CGSizeZero) && !CGSizeEqualToSize(targetPixelSize, CGSizeZero)) {
|
||||
size = CGSizeMake(targetPixelSize.width/scale, targetPixelSize.height/scale);
|
||||
}
|
||||
if (!CGSizeEqualToSize(size, CGSizeZero)) {
|
||||
CGSize pixelSize = CGSizeMake(size.width * scale, size.height * scale);
|
||||
context[SDWebImageContextImageThumbnailPixelSize] = @(pixelSize);
|
||||
}
|
||||
}
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[self sd_setImageWithURL:u
|
||||
placeholderImage:placeholder
|
||||
options:options
|
||||
context:context
|
||||
progress:nil
|
||||
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
||||
if (!error && image && cacheType == SDImageCacheTypeNone) {
|
||||
weakSelf.alpha = 0.0;
|
||||
[UIView animateWithDuration:0.25 animations:^{ weakSelf.alpha = 1.0; }];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)kb_setImageURL:(id)url
|
||||
placeholder:(UIImage *)placeholder
|
||||
cornerRadius:(CGFloat)radius
|
||||
corners:(UIRectCorner)corners
|
||||
borderWidth:(CGFloat)borderWidth
|
||||
borderColor:(UIColor *)borderColor {
|
||||
NSURL *u = _KBURL(url);
|
||||
SDWebImageOptions options = KBWebImageDefaultOptions();
|
||||
|
||||
// 组合圆角 + 缩略(按视图大小)
|
||||
CGFloat scale = UIScreen.mainScreen.scale;
|
||||
CGSize size = self.bounds.size;
|
||||
NSMutableArray<id<SDImageTransformer>> *trans = [NSMutableArray array];
|
||||
if (!CGSizeEqualToSize(size, CGSizeZero)) {
|
||||
// 先按像素缩到视图大小,避免在解码后再裁切浪费内存
|
||||
CGSize pixel = CGSizeMake(size.width * scale, size.height * scale);
|
||||
[trans addObject:[SDImageResizingTransformer transformerWithSize:pixel scaleMode:SDImageScaleModeAspectFill]];
|
||||
}
|
||||
[trans addObject:[SDImageRoundCornerTransformer transformerWithRadius:radius
|
||||
corners:(SDRectCorner)corners
|
||||
borderWidth:borderWidth
|
||||
borderColor:borderColor]];
|
||||
SDImagePipelineTransformer *pipeline = [SDImagePipelineTransformer transformerWithTransformers:trans];
|
||||
|
||||
NSDictionary *context = @{ SDWebImageContextImageTransformer : pipeline };
|
||||
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[self sd_setImageWithURL:u
|
||||
placeholderImage:placeholder
|
||||
options:options
|
||||
context:context
|
||||
progress:nil
|
||||
completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
|
||||
if (!error && image && cacheType == SDImageCacheTypeNone) {
|
||||
weakSelf.alpha = 0.0;
|
||||
[UIView animateWithDuration:0.25 animations:^{ weakSelf.alpha = 1.0; }];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)kb_setAvatarURL:(id)url placeholder:(UIImage *)placeholder {
|
||||
// 圆形:以视图最短边的一半为半径
|
||||
CGSize sz = self.bounds.size;
|
||||
CGFloat r = MIN(sz.width, sz.height) * 0.5;
|
||||
if (r <= 0) {
|
||||
// 若尚未布局,使用占位图尺寸估算
|
||||
r = MIN(placeholder.size.width, placeholder.size.height) * 0.5;
|
||||
}
|
||||
[self kb_setImageURL:url
|
||||
placeholder:placeholder
|
||||
cornerRadius:r
|
||||
corners:UIRectCornerAllCorners
|
||||
borderWidth:0
|
||||
borderColor:nil];
|
||||
}
|
||||
|
||||
- (void)kb_cancelImageLoad {
|
||||
[self sd_cancelCurrentImageLoad];
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user