From 3e8437ae559487362fae3525beb79c534c213a51 Mon Sep 17 00:00:00 2001
From: 单军华
Date: Thu, 12 Jul 2018 13:44:34 +0800
Subject: [PATCH] bug修复和功能优化
---
screendisplay/Pods/SDWebImage/SDWebImage/UIView+WebCache.m | 371 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 371 insertions(+), 0 deletions(-)
diff --git a/screendisplay/Pods/SDWebImage/SDWebImage/UIView+WebCache.m b/screendisplay/Pods/SDWebImage/SDWebImage/UIView+WebCache.m
new file mode 100644
index 0000000..8193cda
--- /dev/null
+++ b/screendisplay/Pods/SDWebImage/SDWebImage/UIView+WebCache.m
@@ -0,0 +1,371 @@
+/*
+ * This file is part of the SDWebImage package.
+ * (c) Olivier Poitrey <rs@dailymotion.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+#import "UIView+WebCache.h"
+#import "objc/runtime.h"
+#import "UIView+WebCacheOperation.h"
+
+NSString * const SDWebImageInternalSetImageGroupKey = @"internalSetImageGroup";
+NSString * const SDWebImageExternalCustomManagerKey = @"externalCustomManager";
+
+const int64_t SDWebImageProgressUnitCountUnknown = 1LL;
+
+static char imageURLKey;
+
+#if SD_UIKIT
+static char TAG_ACTIVITY_INDICATOR;
+static char TAG_ACTIVITY_STYLE;
+static char TAG_ACTIVITY_SHOW;
+#endif
+
+@implementation UIView (WebCache)
+
+- (nullable NSURL *)sd_imageURL {
+ return objc_getAssociatedObject(self, &imageURLKey);
+}
+
+- (NSProgress *)sd_imageProgress {
+ NSProgress *progress = objc_getAssociatedObject(self, @selector(sd_imageProgress));
+ if (!progress) {
+ progress = [[NSProgress alloc] initWithParent:nil userInfo:nil];
+ self.sd_imageProgress = progress;
+ }
+ return progress;
+}
+
+- (void)setSd_imageProgress:(NSProgress *)sd_imageProgress {
+ objc_setAssociatedObject(self, @selector(sd_imageProgress), sd_imageProgress, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (void)sd_internalSetImageWithURL:(nullable NSURL *)url
+ placeholderImage:(nullable UIImage *)placeholder
+ options:(SDWebImageOptions)options
+ operationKey:(nullable NSString *)operationKey
+ setImageBlock:(nullable SDSetImageBlock)setImageBlock
+ progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
+ completed:(nullable SDExternalCompletionBlock)completedBlock {
+ return [self sd_internalSetImageWithURL:url placeholderImage:placeholder options:options operationKey:operationKey setImageBlock:setImageBlock progress:progressBlock completed:completedBlock context:nil];
+}
+
+- (void)sd_internalSetImageWithURL:(nullable NSURL *)url
+ placeholderImage:(nullable UIImage *)placeholder
+ options:(SDWebImageOptions)options
+ operationKey:(nullable NSString *)operationKey
+ setImageBlock:(nullable SDSetImageBlock)setImageBlock
+ progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
+ completed:(nullable SDExternalCompletionBlock)completedBlock
+ context:(nullable NSDictionary<NSString *, id> *)context {
+ NSString *validOperationKey = operationKey ?: NSStringFromClass([self class]);
+ [self sd_cancelImageLoadOperationWithKey:validOperationKey];
+ objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+
+ if (!(options & SDWebImageDelayPlaceholder)) {
+ if ([context valueForKey:SDWebImageInternalSetImageGroupKey]) {
+ dispatch_group_t group = [context valueForKey:SDWebImageInternalSetImageGroupKey];
+ dispatch_group_enter(group);
+ }
+ dispatch_main_async_safe(^{
+ [self sd_setImage:placeholder imageData:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock];
+ });
+ }
+
+ if (url) {
+#if SD_UIKIT
+ // check if activityView is enabled or not
+ if ([self sd_showActivityIndicatorView]) {
+ [self sd_addActivityIndicator];
+ }
+#endif
+
+ // reset the progress
+ self.sd_imageProgress.totalUnitCount = 0;
+ self.sd_imageProgress.completedUnitCount = 0;
+
+ SDWebImageManager *manager;
+ if ([context valueForKey:SDWebImageExternalCustomManagerKey]) {
+ manager = (SDWebImageManager *)[context valueForKey:SDWebImageExternalCustomManagerKey];
+ } else {
+ manager = [SDWebImageManager sharedManager];
+ }
+
+ __weak __typeof(self)wself = self;
+ SDWebImageDownloaderProgressBlock combinedProgressBlock = ^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
+ wself.sd_imageProgress.totalUnitCount = expectedSize;
+ wself.sd_imageProgress.completedUnitCount = receivedSize;
+ if (progressBlock) {
+ progressBlock(receivedSize, expectedSize, targetURL);
+ }
+ };
+ id <SDWebImageOperation> operation = [manager loadImageWithURL:url options:options progress:combinedProgressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
+ __strong __typeof (wself) sself = wself;
+ if (!sself) { return; }
+#if SD_UIKIT
+ [sself sd_removeActivityIndicator];
+#endif
+ // if the progress not been updated, mark it to complete state
+ if (finished && !error && sself.sd_imageProgress.totalUnitCount == 0 && sself.sd_imageProgress.completedUnitCount == 0) {
+ sself.sd_imageProgress.totalUnitCount = SDWebImageProgressUnitCountUnknown;
+ sself.sd_imageProgress.completedUnitCount = SDWebImageProgressUnitCountUnknown;
+ }
+ BOOL shouldCallCompletedBlock = finished || (options & SDWebImageAvoidAutoSetImage);
+ BOOL shouldNotSetImage = ((image && (options & SDWebImageAvoidAutoSetImage)) ||
+ (!image && !(options & SDWebImageDelayPlaceholder)));
+ SDWebImageNoParamsBlock callCompletedBlockClojure = ^{
+ if (!sself) { return; }
+ if (!shouldNotSetImage) {
+ [sself sd_setNeedsLayout];
+ }
+ if (completedBlock && shouldCallCompletedBlock) {
+ completedBlock(image, error, cacheType, url);
+ }
+ };
+
+ // case 1a: we got an image, but the SDWebImageAvoidAutoSetImage flag is set
+ // OR
+ // case 1b: we got no image and the SDWebImageDelayPlaceholder is not set
+ if (shouldNotSetImage) {
+ dispatch_main_async_safe(callCompletedBlockClojure);
+ return;
+ }
+
+ UIImage *targetImage = nil;
+ NSData *targetData = nil;
+ if (image) {
+ // case 2a: we got an image and the SDWebImageAvoidAutoSetImage is not set
+ targetImage = image;
+ targetData = data;
+ } else if (options & SDWebImageDelayPlaceholder) {
+ // case 2b: we got no image and the SDWebImageDelayPlaceholder flag is set
+ targetImage = placeholder;
+ targetData = nil;
+ }
+
+#if SD_UIKIT || SD_MAC
+ // check whether we should use the image transition
+ SDWebImageTransition *transition = nil;
+ if (finished && (options & SDWebImageForceTransition || cacheType == SDImageCacheTypeNone)) {
+ transition = sself.sd_imageTransition;
+ }
+#endif
+ if ([context valueForKey:SDWebImageInternalSetImageGroupKey]) {
+ dispatch_group_t group = [context valueForKey:SDWebImageInternalSetImageGroupKey];
+ dispatch_group_enter(group);
+ dispatch_main_async_safe(^{
+#if SD_UIKIT || SD_MAC
+ [sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:transition cacheType:cacheType imageURL:imageURL];
+#else
+ [sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock];
+#endif
+ });
+ // ensure completion block is called after custom setImage process finish
+ dispatch_group_notify(group, dispatch_get_main_queue(), ^{
+ callCompletedBlockClojure();
+ });
+ } else {
+ dispatch_main_async_safe(^{
+#if SD_UIKIT || SD_MAC
+ [sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:transition cacheType:cacheType imageURL:imageURL];
+#else
+ [sself sd_setImage:targetImage imageData:targetData basedOnClassOrViaCustomSetImageBlock:setImageBlock];
+#endif
+ callCompletedBlockClojure();
+ });
+ }
+ }];
+ [self sd_setImageLoadOperation:operation forKey:validOperationKey];
+ } else {
+ dispatch_main_async_safe(^{
+#if SD_UIKIT
+ [self sd_removeActivityIndicator];
+#endif
+ if (completedBlock) {
+ NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
+ completedBlock(nil, error, SDImageCacheTypeNone, url);
+ }
+ });
+ }
+}
+
+- (void)sd_cancelCurrentImageLoad {
+ [self sd_cancelImageLoadOperationWithKey:NSStringFromClass([self class])];
+}
+
+- (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock {
+#if SD_UIKIT || SD_MAC
+ [self sd_setImage:image imageData:imageData basedOnClassOrViaCustomSetImageBlock:setImageBlock transition:nil cacheType:0 imageURL:nil];
+#else
+ // watchOS does not support view transition. Simplify the logic
+ if (setImageBlock) {
+ setImageBlock(image, imageData);
+ } else if ([self isKindOfClass:[UIImageView class]]) {
+ UIImageView *imageView = (UIImageView *)self;
+ [imageView setImage:image];
+ }
+#endif
+}
+
+#if SD_UIKIT || SD_MAC
+- (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock transition:(SDWebImageTransition *)transition cacheType:(SDImageCacheType)cacheType imageURL:(NSURL *)imageURL {
+ UIView *view = self;
+ SDSetImageBlock finalSetImageBlock;
+ if (setImageBlock) {
+ finalSetImageBlock = setImageBlock;
+ } else if ([view isKindOfClass:[UIImageView class]]) {
+ UIImageView *imageView = (UIImageView *)view;
+ finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData) {
+ imageView.image = setImage;
+ };
+ }
+#if SD_UIKIT
+ else if ([view isKindOfClass:[UIButton class]]) {
+ UIButton *button = (UIButton *)view;
+ finalSetImageBlock = ^(UIImage *setImage, NSData *setImageData){
+ [button setImage:setImage forState:UIControlStateNormal];
+ };
+ }
+#endif
+
+ if (transition) {
+#if SD_UIKIT
+ [UIView transitionWithView:view duration:0 options:0 animations:^{
+ // 0 duration to let UIKit render placeholder and prepares block
+ if (transition.prepares) {
+ transition.prepares(view, image, imageData, cacheType, imageURL);
+ }
+ } completion:^(BOOL finished) {
+ [UIView transitionWithView:view duration:transition.duration options:transition.animationOptions animations:^{
+ if (finalSetImageBlock && !transition.avoidAutoSetImage) {
+ finalSetImageBlock(image, imageData);
+ }
+ if (transition.animations) {
+ transition.animations(view, image);
+ }
+ } completion:transition.completion];
+ }];
+#elif SD_MAC
+ [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull prepareContext) {
+ // 0 duration to let AppKit render placeholder and prepares block
+ prepareContext.duration = 0;
+ if (transition.prepares) {
+ transition.prepares(view, image, imageData, cacheType, imageURL);
+ }
+ } completionHandler:^{
+ [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) {
+ context.duration = transition.duration;
+ context.timingFunction = transition.timingFunction;
+ context.allowsImplicitAnimation = (transition.animationOptions & SDWebImageAnimationOptionAllowsImplicitAnimation);
+ if (finalSetImageBlock && !transition.avoidAutoSetImage) {
+ finalSetImageBlock(image, imageData);
+ }
+ if (transition.animations) {
+ transition.animations(view, image);
+ }
+ } completionHandler:^{
+ if (transition.completion) {
+ transition.completion(YES);
+ }
+ }];
+ }];
+#endif
+ } else {
+ if (finalSetImageBlock) {
+ finalSetImageBlock(image, imageData);
+ }
+ }
+}
+#endif
+
+- (void)sd_setNeedsLayout {
+#if SD_UIKIT
+ [self setNeedsLayout];
+#elif SD_MAC
+ [self setNeedsLayout:YES];
+#elif SD_WATCH
+ // Do nothing because WatchKit automatically layout the view after property change
+#endif
+}
+
+#if SD_UIKIT || SD_MAC
+
+#pragma mark - Image Transition
+- (SDWebImageTransition *)sd_imageTransition {
+ return objc_getAssociatedObject(self, @selector(sd_imageTransition));
+}
+
+- (void)setSd_imageTransition:(SDWebImageTransition *)sd_imageTransition {
+ objc_setAssociatedObject(self, @selector(sd_imageTransition), sd_imageTransition, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+#if SD_UIKIT
+
+#pragma mark - Activity indicator
+- (UIActivityIndicatorView *)activityIndicator {
+ return (UIActivityIndicatorView *)objc_getAssociatedObject(self, &TAG_ACTIVITY_INDICATOR);
+}
+
+- (void)setActivityIndicator:(UIActivityIndicatorView *)activityIndicator {
+ objc_setAssociatedObject(self, &TAG_ACTIVITY_INDICATOR, activityIndicator, OBJC_ASSOCIATION_RETAIN);
+}
+
+- (void)sd_setShowActivityIndicatorView:(BOOL)show {
+ objc_setAssociatedObject(self, &TAG_ACTIVITY_SHOW, @(show), OBJC_ASSOCIATION_RETAIN);
+}
+
+- (BOOL)sd_showActivityIndicatorView {
+ return [objc_getAssociatedObject(self, &TAG_ACTIVITY_SHOW) boolValue];
+}
+
+- (void)sd_setIndicatorStyle:(UIActivityIndicatorViewStyle)style{
+ objc_setAssociatedObject(self, &TAG_ACTIVITY_STYLE, [NSNumber numberWithInt:style], OBJC_ASSOCIATION_RETAIN);
+}
+
+- (int)sd_getIndicatorStyle{
+ return [objc_getAssociatedObject(self, &TAG_ACTIVITY_STYLE) intValue];
+}
+
+- (void)sd_addActivityIndicator {
+ dispatch_main_async_safe(^{
+ if (!self.activityIndicator) {
+ self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:[self sd_getIndicatorStyle]];
+ self.activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;
+
+ [self addSubview:self.activityIndicator];
+
+ [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator
+ attribute:NSLayoutAttributeCenterX
+ relatedBy:NSLayoutRelationEqual
+ toItem:self
+ attribute:NSLayoutAttributeCenterX
+ multiplier:1.0
+ constant:0.0]];
+ [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator
+ attribute:NSLayoutAttributeCenterY
+ relatedBy:NSLayoutRelationEqual
+ toItem:self
+ attribute:NSLayoutAttributeCenterY
+ multiplier:1.0
+ constant:0.0]];
+ }
+ [self.activityIndicator startAnimating];
+ });
+}
+
+- (void)sd_removeActivityIndicator {
+ dispatch_main_async_safe(^{
+ if (self.activityIndicator) {
+ [self.activityIndicator removeFromSuperview];
+ self.activityIndicator = nil;
+ }
+ });
+}
+
+#endif
+
+#endif
+
+@end
--
Gitblit v1.8.0