Authored by Bogdan Poplauschi

Refactored all the duplicate code from our WebCache categories into a UIView+Web…

…Cache category. All the other categories will make calls to this one. Customization of setting the image is done via the setImageBlock and the operationKey
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 #import "DetailViewController.h" 11 #import "DetailViewController.h"
12 #import <SDWebImage/FLAnimatedImageView.h> 12 #import <SDWebImage/FLAnimatedImageView.h>
13 #import <SDWebImage/FLAnimatedImageView+WebCache.h> 13 #import <SDWebImage/FLAnimatedImageView+WebCache.h>
  14 +#import <SDWebImage/UIView+WebCache.h>
14 15
15 16
16 @interface MyCustomTableViewCell : UITableViewCell 17 @interface MyCustomTableViewCell : UITableViewCell
@@ -297,6 +297,18 @@ @@ -297,6 +297,18 @@
297 431BB6F91D06D2C1006A3455 /* UIImage+GIF.h in Headers */ = {isa = PBXBuildFile; fileRef = A18A6CC5172DC28500419892 /* UIImage+GIF.h */; settings = {ATTRIBUTES = (Public, ); }; }; 297 431BB6F91D06D2C1006A3455 /* UIImage+GIF.h in Headers */ = {isa = PBXBuildFile; fileRef = A18A6CC5172DC28500419892 /* UIImage+GIF.h */; settings = {ATTRIBUTES = (Public, ); }; };
298 431BB6FA1D06D2C1006A3455 /* SDWebImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 53922D8B148C56230056699D /* SDWebImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; }; 298 431BB6FA1D06D2C1006A3455 /* SDWebImageDownloader.h in Headers */ = {isa = PBXBuildFile; fileRef = 53922D8B148C56230056699D /* SDWebImageDownloader.h */; settings = {ATTRIBUTES = (Public, ); }; };
299 431BB6FC1D06D2C1006A3455 /* SDWebImageDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 53922D89148C56230056699D /* SDWebImageDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; 299 431BB6FC1D06D2C1006A3455 /* SDWebImageDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 53922D89148C56230056699D /* SDWebImageDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
  300 + 4369C2771D9807EC007E863A /* UIView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 4369C2751D9807EC007E863A /* UIView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
  301 + 4369C2781D9807EC007E863A /* UIView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 4369C2751D9807EC007E863A /* UIView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
  302 + 4369C2791D9807EC007E863A /* UIView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 4369C2751D9807EC007E863A /* UIView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
  303 + 4369C27A1D9807EC007E863A /* UIView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 4369C2751D9807EC007E863A /* UIView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
  304 + 4369C27B1D9807EC007E863A /* UIView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 4369C2751D9807EC007E863A /* UIView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
  305 + 4369C27C1D9807EC007E863A /* UIView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 4369C2751D9807EC007E863A /* UIView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
  306 + 4369C27E1D9807EC007E863A /* UIView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4369C2761D9807EC007E863A /* UIView+WebCache.m */; };
  307 + 4369C27F1D9807EC007E863A /* UIView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4369C2761D9807EC007E863A /* UIView+WebCache.m */; };
  308 + 4369C2801D9807EC007E863A /* UIView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4369C2761D9807EC007E863A /* UIView+WebCache.m */; };
  309 + 4369C2811D9807EC007E863A /* UIView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4369C2761D9807EC007E863A /* UIView+WebCache.m */; };
  310 + 4369C2821D9807EC007E863A /* UIView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4369C2761D9807EC007E863A /* UIView+WebCache.m */; };
  311 + 4369C2831D9807EC007E863A /* UIView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 4369C2761D9807EC007E863A /* UIView+WebCache.m */; };
300 438096721CDFC08200DC626B /* MKAnnotationView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 535699B415113E7300A4C397 /* MKAnnotationView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; }; 312 438096721CDFC08200DC626B /* MKAnnotationView+WebCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 535699B415113E7300A4C397 /* MKAnnotationView+WebCache.h */; settings = {ATTRIBUTES = (Public, ); }; };
301 438096731CDFC08F00DC626B /* MKAnnotationView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 535699B515113E7300A4C397 /* MKAnnotationView+WebCache.m */; }; 313 438096731CDFC08F00DC626B /* MKAnnotationView+WebCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 535699B515113E7300A4C397 /* MKAnnotationView+WebCache.m */; };
302 438096741CDFC09C00DC626B /* UIImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 53EDFB911762547C00698166 /* UIImage+WebP.h */; settings = {ATTRIBUTES = (Public, ); }; }; 314 438096741CDFC09C00DC626B /* UIImage+WebP.h in Headers */ = {isa = PBXBuildFile; fileRef = 53EDFB911762547C00698166 /* UIImage+WebP.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -891,6 +903,8 @@ @@ -891,6 +903,8 @@
891 00733A4C1BC487C000A5A117 /* SDWebImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 903 00733A4C1BC487C000A5A117 /* SDWebImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; };
892 4314D1991D0E0E3B004B36C9 /* libSDWebImage watchOS static.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libSDWebImage watchOS static.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 904 4314D1991D0E0E3B004B36C9 /* libSDWebImage watchOS static.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libSDWebImage watchOS static.a"; sourceTree = BUILT_PRODUCTS_DIR; };
893 431BB7031D06D2C1006A3455 /* SDWebImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 905 431BB7031D06D2C1006A3455 /* SDWebImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; };
  906 + 4369C2751D9807EC007E863A /* UIView+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIView+WebCache.h"; path = "SDWebImage/UIView+WebCache.h"; sourceTree = "<group>"; };
  907 + 4369C2761D9807EC007E863A /* UIView+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIView+WebCache.m"; path = "SDWebImage/UIView+WebCache.m"; sourceTree = "<group>"; };
894 4397D2F21D0DDD8C00BB2784 /* SDWebImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 908 4397D2F21D0DDD8C00BB2784 /* SDWebImage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImage.framework; sourceTree = BUILT_PRODUCTS_DIR; };
895 4397D2F41D0DE2DF00BB2784 /* NSImage+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSImage+WebCache.h"; path = "SDWebImage/NSImage+WebCache.h"; sourceTree = "<group>"; }; 909 4397D2F41D0DE2DF00BB2784 /* NSImage+WebCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSImage+WebCache.h"; path = "SDWebImage/NSImage+WebCache.h"; sourceTree = "<group>"; };
896 4397D2F51D0DE2DF00BB2784 /* NSImage+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSImage+WebCache.m"; path = "SDWebImage/NSImage+WebCache.m"; sourceTree = "<group>"; }; 910 4397D2F51D0DE2DF00BB2784 /* NSImage+WebCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSImage+WebCache.m"; path = "SDWebImage/NSImage+WebCache.m"; sourceTree = "<group>"; };
@@ -1116,6 +1130,8 @@ @@ -1116,6 +1130,8 @@
1116 ABBE71A618C43B4D00B75E91 /* UIImageView+HighlightedWebCache.m */, 1130 ABBE71A618C43B4D00B75E91 /* UIImageView+HighlightedWebCache.m */,
1117 53922D95148C56230056699D /* UIImageView+WebCache.h */, 1131 53922D95148C56230056699D /* UIImageView+WebCache.h */,
1118 53922D96148C56230056699D /* UIImageView+WebCache.m */, 1132 53922D96148C56230056699D /* UIImageView+WebCache.m */,
  1133 + 4369C2751D9807EC007E863A /* UIView+WebCache.h */,
  1134 + 4369C2761D9807EC007E863A /* UIView+WebCache.m */,
1119 ); 1135 );
1120 name = "WebCache Categories"; 1136 name = "WebCache Categories";
1121 path = ..; 1137 path = ..;
@@ -1438,6 +1454,7 @@ @@ -1438,6 +1454,7 @@
1438 431739561CDFC8B70008FEB9 /* demux.h in Headers */, 1454 431739561CDFC8B70008FEB9 /* demux.h in Headers */,
1439 4317394D1CDFC8B20008FEB9 /* utils.h in Headers */, 1455 4317394D1CDFC8B20008FEB9 /* utils.h in Headers */,
1440 4397D2F81D0DF44200BB2784 /* MKAnnotationView+WebCache.h in Headers */, 1456 4397D2F81D0DF44200BB2784 /* MKAnnotationView+WebCache.h in Headers */,
  1457 + 4369C27A1D9807EC007E863A /* UIView+WebCache.h in Headers */,
1441 431739451CDFC8B20008FEB9 /* quant_levels_dec.h in Headers */, 1458 431739451CDFC8B20008FEB9 /* quant_levels_dec.h in Headers */,
1442 431739361CDFC8B20008FEB9 /* bit_reader_inl.h in Headers */, 1459 431739361CDFC8B20008FEB9 /* bit_reader_inl.h in Headers */,
1443 4317393A1CDFC8B20008FEB9 /* color_cache.h in Headers */, 1460 4317393A1CDFC8B20008FEB9 /* color_cache.h in Headers */,
@@ -1524,6 +1541,7 @@ @@ -1524,6 +1541,7 @@
1524 4314D17B1D0E0E3B004B36C9 /* huffman_encode.h in Headers */, 1541 4314D17B1D0E0E3B004B36C9 /* huffman_encode.h in Headers */,
1525 43DA7CD91D10865E0028BE58 /* dsp.h in Headers */, 1542 43DA7CD91D10865E0028BE58 /* dsp.h in Headers */,
1526 4314D17C1D0E0E3B004B36C9 /* UIImage+WebP.h in Headers */, 1543 4314D17C1D0E0E3B004B36C9 /* UIImage+WebP.h in Headers */,
  1544 + 4369C2781D9807EC007E863A /* UIView+WebCache.h in Headers */,
1527 4314D17D1D0E0E3B004B36C9 /* SDWebImagePrefetcher.h in Headers */, 1545 4314D17D1D0E0E3B004B36C9 /* SDWebImagePrefetcher.h in Headers */,
1528 4314D17E1D0E0E3B004B36C9 /* bit_writer.h in Headers */, 1546 4314D17E1D0E0E3B004B36C9 /* bit_writer.h in Headers */,
1529 43DA7CF01D10865E0028BE58 /* neon.h in Headers */, 1547 43DA7CF01D10865E0028BE58 /* neon.h in Headers */,
@@ -1585,6 +1603,7 @@ @@ -1585,6 +1603,7 @@
1585 43DA7D931D1086600028BE58 /* lossless.h in Headers */, 1603 43DA7D931D1086600028BE58 /* lossless.h in Headers */,
1586 431BB6EE1D06D2C1006A3455 /* NSData+ImageContentType.h in Headers */, 1604 431BB6EE1D06D2C1006A3455 /* NSData+ImageContentType.h in Headers */,
1587 431BB6EF1D06D2C1006A3455 /* SDWebImagePrefetcher.h in Headers */, 1605 431BB6EF1D06D2C1006A3455 /* SDWebImagePrefetcher.h in Headers */,
  1606 + 4369C27B1D9807EC007E863A /* UIView+WebCache.h in Headers */,
1588 431BB6F01D06D2C1006A3455 /* SDWebImageOperation.h in Headers */, 1607 431BB6F01D06D2C1006A3455 /* SDWebImageOperation.h in Headers */,
1589 43A62A201D0E0A800089D7DD /* mux_types.h in Headers */, 1608 43A62A201D0E0A800089D7DD /* mux_types.h in Headers */,
1590 43A62A2F1D0E0A860089D7DD /* huffman_encode.h in Headers */, 1609 43A62A2F1D0E0A860089D7DD /* huffman_encode.h in Headers */,
@@ -1621,6 +1640,7 @@ @@ -1621,6 +1640,7 @@
1621 4397D2C31D0DDD8C00BB2784 /* SDWebImageManager.h in Headers */, 1640 4397D2C31D0DDD8C00BB2784 /* SDWebImageManager.h in Headers */,
1622 4397D2C41D0DDD8C00BB2784 /* SDImageCache.h in Headers */, 1641 4397D2C41D0DDD8C00BB2784 /* SDImageCache.h in Headers */,
1623 4397D2C51D0DDD8C00BB2784 /* UIImageView+WebCache.h in Headers */, 1642 4397D2C51D0DDD8C00BB2784 /* UIImageView+WebCache.h in Headers */,
  1643 + 4369C27C1D9807EC007E863A /* UIView+WebCache.h in Headers */,
1624 4397D2C61D0DDD8C00BB2784 /* random.h in Headers */, 1644 4397D2C61D0DDD8C00BB2784 /* random.h in Headers */,
1625 4397D2C71D0DDD8C00BB2784 /* rescaler.h in Headers */, 1645 4397D2C71D0DDD8C00BB2784 /* rescaler.h in Headers */,
1626 43DA7DE11D10867D0028BE58 /* extras.h in Headers */, 1646 43DA7DE11D10867D0028BE58 /* extras.h in Headers */,
@@ -1675,6 +1695,7 @@ @@ -1675,6 +1695,7 @@
1675 431739211CDFC8B20008FEB9 /* endian_inl.h in Headers */, 1695 431739211CDFC8B20008FEB9 /* endian_inl.h in Headers */,
1676 43CE757D1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */, 1696 43CE757D1CFE9427006C64D0 /* FLAnimatedImageView.h in Headers */,
1677 431739541CDFC8B70008FEB9 /* types.h in Headers */, 1697 431739541CDFC8B70008FEB9 /* types.h in Headers */,
  1698 + 4369C2791D9807EC007E863A /* UIView+WebCache.h in Headers */,
1678 431738C51CDFC8A30008FEB9 /* alphai.h in Headers */, 1699 431738C51CDFC8A30008FEB9 /* alphai.h in Headers */,
1679 4A2CAE041AB4BB5400B6BC39 /* SDWebImage.h in Headers */, 1700 4A2CAE041AB4BB5400B6BC39 /* SDWebImage.h in Headers */,
1680 431739511CDFC8B70008FEB9 /* format_constants.h in Headers */, 1701 431739511CDFC8B70008FEB9 /* format_constants.h in Headers */,
@@ -1758,6 +1779,7 @@ @@ -1758,6 +1779,7 @@
1758 431738BD1CDFC2660008FEB9 /* decode.h in Headers */, 1779 431738BD1CDFC2660008FEB9 /* decode.h in Headers */,
1759 53761319155AD0D5005750A4 /* SDWebImageDecoder.h in Headers */, 1780 53761319155AD0D5005750A4 /* SDWebImageDecoder.h in Headers */,
1760 5376131A155AD0D5005750A4 /* SDWebImageDownloader.h in Headers */, 1781 5376131A155AD0D5005750A4 /* SDWebImageDownloader.h in Headers */,
  1782 + 4369C2771D9807EC007E863A /* UIView+WebCache.h in Headers */,
1761 5376131C155AD0D5005750A4 /* SDWebImageManager.h in Headers */, 1783 5376131C155AD0D5005750A4 /* SDWebImageManager.h in Headers */,
1762 431738B01CDFC2630008FEB9 /* huffman_encode.h in Headers */, 1784 431738B01CDFC2630008FEB9 /* huffman_encode.h in Headers */,
1763 438096741CDFC09C00DC626B /* UIImage+WebP.h in Headers */, 1785 438096741CDFC09C00DC626B /* UIImage+WebP.h in Headers */,
@@ -2092,6 +2114,7 @@ @@ -2092,6 +2114,7 @@
2092 43DA7D681D1086600028BE58 /* yuv_mips_dsp_r2.c in Sources */, 2114 43DA7D681D1086600028BE58 /* yuv_mips_dsp_r2.c in Sources */,
2093 43DA7D651D1086600028BE58 /* upsampling_neon.c in Sources */, 2115 43DA7D651D1086600028BE58 /* upsampling_neon.c in Sources */,
2094 43DA7D371D1086600028BE58 /* alpha_processing.c in Sources */, 2116 43DA7D371D1086600028BE58 /* alpha_processing.c in Sources */,
  2117 + 4369C2811D9807EC007E863A /* UIView+WebCache.m in Sources */,
2095 43DA7D691D1086600028BE58 /* yuv_mips32.c in Sources */, 2118 43DA7D691D1086600028BE58 /* yuv_mips32.c in Sources */,
2096 43DA7D5F1D1086600028BE58 /* rescaler_mips_dsp_r2.c in Sources */, 2119 43DA7D5F1D1086600028BE58 /* rescaler_mips_dsp_r2.c in Sources */,
2097 00733A5E1BC4880000A5A117 /* UIImage+MultiFormat.m in Sources */, 2120 00733A5E1BC4880000A5A117 /* UIImage+MultiFormat.m in Sources */,
@@ -2123,6 +2146,7 @@ @@ -2123,6 +2146,7 @@
2123 43DA7CDB1D10865E0028BE58 /* enc_mips_dsp_r2.c in Sources */, 2146 43DA7CDB1D10865E0028BE58 /* enc_mips_dsp_r2.c in Sources */,
2124 4314D12F1D0E0E3B004B36C9 /* thread.c in Sources */, 2147 4314D12F1D0E0E3B004B36C9 /* thread.c in Sources */,
2125 4314D1311D0E0E3B004B36C9 /* SDWebImageDownloader.m in Sources */, 2148 4314D1311D0E0E3B004B36C9 /* SDWebImageDownloader.m in Sources */,
  2149 + 4369C27F1D9807EC007E863A /* UIView+WebCache.m in Sources */,
2126 43DA7CC91D10865E0028BE58 /* alpha_processing.c in Sources */, 2150 43DA7CC91D10865E0028BE58 /* alpha_processing.c in Sources */,
2127 4314D1321D0E0E3B004B36C9 /* filters.c in Sources */, 2151 4314D1321D0E0E3B004B36C9 /* filters.c in Sources */,
2128 4314D1341D0E0E3B004B36C9 /* UIImage+WebP.m in Sources */, 2152 4314D1341D0E0E3B004B36C9 /* UIImage+WebP.m in Sources */,
@@ -2220,6 +2244,7 @@ @@ -2220,6 +2244,7 @@
2220 43DA7D801D1086600028BE58 /* enc_mips_dsp_r2.c in Sources */, 2244 43DA7D801D1086600028BE58 /* enc_mips_dsp_r2.c in Sources */,
2221 43A62A631D0E0A8F0089D7DD /* vp8l.c in Sources */, 2245 43A62A631D0E0A8F0089D7DD /* vp8l.c in Sources */,
2222 431BB6A31D06D2C1006A3455 /* UIImageView+WebCache.m in Sources */, 2246 431BB6A31D06D2C1006A3455 /* UIImageView+WebCache.m in Sources */,
  2247 + 4369C2821D9807EC007E863A /* UIView+WebCache.m in Sources */,
2223 43DA7D6E1D1086600028BE58 /* alpha_processing.c in Sources */, 2248 43DA7D6E1D1086600028BE58 /* alpha_processing.c in Sources */,
2224 43A62A5E1D0E0A8F0089D7DD /* io.c in Sources */, 2249 43A62A5E1D0E0A8F0089D7DD /* io.c in Sources */,
2225 43A62A321D0E0A860089D7DD /* quant_levels_dec.c in Sources */, 2250 43A62A321D0E0A860089D7DD /* quant_levels_dec.c in Sources */,
@@ -2375,6 +2400,7 @@ @@ -2375,6 +2400,7 @@
2375 43DA7DB01D1086610028BE58 /* dec_mips32.c in Sources */, 2400 43DA7DB01D1086610028BE58 /* dec_mips32.c in Sources */,
2376 43DA7DAA1D1086610028BE58 /* cost_mips32.c in Sources */, 2401 43DA7DAA1D1086610028BE58 /* cost_mips32.c in Sources */,
2377 43DA7DAB1D1086610028BE58 /* cost_sse2.c in Sources */, 2402 43DA7DAB1D1086610028BE58 /* cost_sse2.c in Sources */,
  2403 + 4369C2831D9807EC007E863A /* UIView+WebCache.m in Sources */,
2378 43DA7DB71D1086610028BE58 /* enc_mips_dsp_r2.c in Sources */, 2404 43DA7DB71D1086610028BE58 /* enc_mips_dsp_r2.c in Sources */,
2379 43DA7DC11D1086610028BE58 /* lossless_enc_mips32.c in Sources */, 2405 43DA7DC11D1086610028BE58 /* lossless_enc_mips32.c in Sources */,
2380 43DA7DBC1D1086610028BE58 /* enc.c in Sources */, 2406 43DA7DBC1D1086610028BE58 /* enc.c in Sources */,
@@ -2486,6 +2512,7 @@ @@ -2486,6 +2512,7 @@
2486 43DA7D311D10865F0028BE58 /* yuv_mips_dsp_r2.c in Sources */, 2512 43DA7D311D10865F0028BE58 /* yuv_mips_dsp_r2.c in Sources */,
2487 43DA7D2E1D10865F0028BE58 /* upsampling_neon.c in Sources */, 2513 43DA7D2E1D10865F0028BE58 /* upsampling_neon.c in Sources */,
2488 43DA7D001D10865F0028BE58 /* alpha_processing.c in Sources */, 2514 43DA7D001D10865F0028BE58 /* alpha_processing.c in Sources */,
  2515 + 4369C2801D9807EC007E863A /* UIView+WebCache.m in Sources */,
2489 43DA7D321D10865F0028BE58 /* yuv_mips32.c in Sources */, 2516 43DA7D321D10865F0028BE58 /* yuv_mips32.c in Sources */,
2490 43DA7D281D10865F0028BE58 /* rescaler_mips_dsp_r2.c in Sources */, 2517 43DA7D281D10865F0028BE58 /* rescaler_mips_dsp_r2.c in Sources */,
2491 431738C81CDFC8A30008FEB9 /* frame.c in Sources */, 2518 431738C81CDFC8A30008FEB9 /* frame.c in Sources */,
@@ -2587,6 +2614,7 @@ @@ -2587,6 +2614,7 @@
2587 43DA7CC31D1086570028BE58 /* yuv_mips_dsp_r2.c in Sources */, 2614 43DA7CC31D1086570028BE58 /* yuv_mips_dsp_r2.c in Sources */,
2588 43DA7CC01D1086570028BE58 /* upsampling_neon.c in Sources */, 2615 43DA7CC01D1086570028BE58 /* upsampling_neon.c in Sources */,
2589 43DA7C921D1086570028BE58 /* alpha_processing.c in Sources */, 2616 43DA7C921D1086570028BE58 /* alpha_processing.c in Sources */,
  2617 + 4369C27E1D9807EC007E863A /* UIView+WebCache.m in Sources */,
2590 43DA7CC41D1086570028BE58 /* yuv_mips32.c in Sources */, 2618 43DA7CC41D1086570028BE58 /* yuv_mips32.c in Sources */,
2591 43DA7CBA1D1086570028BE58 /* rescaler_mips_dsp_r2.c in Sources */, 2619 43DA7CBA1D1086570028BE58 /* rescaler_mips_dsp_r2.c in Sources */,
2592 4317387C1CDFC2580008FEB9 /* frame.c in Sources */, 2620 4317387C1CDFC2580008FEB9 /* frame.c in Sources */,
@@ -11,9 +11,9 @@ @@ -11,9 +11,9 @@
11 #if SD_UIKIT 11 #if SD_UIKIT
12 12
13 #if COCOAPODS 13 #if COCOAPODS
14 - @import FLAnimatedImage; 14 +@import FLAnimatedImage;
15 #else 15 #else
16 - #import "FLAnimatedImageView.h" 16 +#import "FLAnimatedImageView.h"
17 #endif 17 #endif
18 18
19 #import "SDWebImageManager.h" 19 #import "SDWebImageManager.h"
@@ -26,14 +26,6 @@ @@ -26,14 +26,6 @@
26 @interface FLAnimatedImageView (WebCache) 26 @interface FLAnimatedImageView (WebCache)
27 27
28 /** 28 /**
29 - * Get the current image URL.  
30 - *  
31 - * Note that because of the limitations of categories this property can get out of sync  
32 - * if you use setImage: directly.  
33 - */  
34 -- (nullable NSURL *)sd_imageURL;  
35 -  
36 -/**  
37 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images 29 * Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
38 * The download is asynchronous and cached. 30 * The download is asynchronous and cached.
39 * 31 *
@@ -136,11 +128,6 @@ @@ -136,11 +128,6 @@
136 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 128 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
137 completed:(nullable SDExternalCompletionBlock)completedBlock; 129 completed:(nullable SDExternalCompletionBlock)completedBlock;
138 130
139 -/**  
140 - * Cancel the image load  
141 - */  
142 -- (void)sd_cancelCurrentImageLoad;  
143 -  
144 @end 131 @end
145 132
146 #endif 133 #endif
@@ -11,19 +11,13 @@ @@ -11,19 +11,13 @@
11 #import "FLAnimatedImageView+WebCache.h" 11 #import "FLAnimatedImageView+WebCache.h"
12 #import "objc/runtime.h" 12 #import "objc/runtime.h"
13 #import "UIView+WebCacheOperation.h" 13 #import "UIView+WebCacheOperation.h"
  14 +#import "UIView+WebCache.h"
14 #import "NSData+ImageContentType.h" 15 #import "NSData+ImageContentType.h"
15 #import "FLAnimatedImage.h" 16 #import "FLAnimatedImage.h"
16 #import "UIImageView+WebCache.h" 17 #import "UIImageView+WebCache.h"
17 18
18 -static char imageURLKey;  
19 -  
20 -  
21 @implementation FLAnimatedImageView (WebCache) 19 @implementation FLAnimatedImageView (WebCache)
22 20
23 -- (nullable NSURL *)sd_imageURL {  
24 - return objc_getAssociatedObject(self, &imageURLKey);  
25 -}  
26 -  
27 - (void)sd_setImageWithURL:(nullable NSURL *)url { 21 - (void)sd_setImageWithURL:(nullable NSURL *)url {
28 [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; 22 [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
29 } 23 }
@@ -53,70 +47,25 @@ static char imageURLKey; @@ -53,70 +47,25 @@ static char imageURLKey;
53 options:(SDWebImageOptions)options 47 options:(SDWebImageOptions)options
54 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 48 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
55 completed:(nullable SDExternalCompletionBlock)completedBlock { 49 completed:(nullable SDExternalCompletionBlock)completedBlock {
56 - [self sd_cancelCurrentImageLoad];  
57 - objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);  
58 -  
59 - if (!(options & SDWebImageDelayPlaceholder)) {  
60 - dispatch_main_async_safe(^{  
61 - self.image = placeholder;  
62 - });  
63 - }  
64 -  
65 - if (url) {  
66 - // check if activityView is enabled or not  
67 - if ([self showActivityIndicatorView]) {  
68 - [self addActivityIndicator];  
69 - }  
70 -  
71 - __weak __typeof(self)wself = self;  
72 - id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {  
73 - if (!wself) return;  
74 - dispatch_main_sync_safe(^{  
75 - [wself removeActivityIndicator];  
76 -  
77 - if (!wself) return;  
78 - if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock) {  
79 - completedBlock(image, error, cacheType, url);  
80 - return;  
81 - } else if (image) {  
82 - SDImageFormat imageFormat = [NSData sd_imageFormatForImageData:data];  
83 - if (imageFormat == SDImageFormatGIF) {  
84 - wself.animatedImage = [FLAnimatedImage animatedImageWithGIFData:data];  
85 - wself.image = nil;  
86 - } else {  
87 - wself.image = image;  
88 - wself.animatedImage = nil;  
89 - }  
90 - [wself setNeedsLayout];  
91 - } else {  
92 - if ((options & SDWebImageDelayPlaceholder)) {  
93 - wself.image = placeholder;  
94 - [wself setNeedsLayout];  
95 - }  
96 - }  
97 - if (completedBlock && finished) {  
98 - completedBlock(image, error, cacheType, url);  
99 - }  
100 - });  
101 - }];  
102 - [self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];  
103 - } else {  
104 - dispatch_main_async_safe(^{  
105 - [self removeActivityIndicator];  
106 -  
107 - if (completedBlock) {  
108 - NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];  
109 - completedBlock(nil, error, SDImageCacheTypeNone, url);  
110 - }  
111 - });  
112 - }  
113 -}  
114 -  
115 -- (void)sd_cancelCurrentImageLoad {  
116 - [self sd_cancelImageLoadOperationWithKey:@"UIImageViewImageLoad"]; 50 + __weak typeof(self)weakSelf = self;
  51 + [self sd_internalSetImageWithURL:url
  52 + placeholderImage:placeholder
  53 + options:options
  54 + operationKey:nil
  55 + setImageBlock:^(UIImage *image, NSData *imageData) {
  56 + SDImageFormat imageFormat = [NSData sd_imageFormatForImageData:data];
  57 + if (imageFormat == SDImageFormatGIF) {
  58 + weakSelf.animatedImage = [FLAnimatedImage animatedImageWithGIFData:data];
  59 + weakSelf.image = nil;
  60 + } else {
  61 + weakSelf.image = image;
  62 + weakSelf.animatedImage = nil;
  63 + }
  64 + }
  65 + progress:progressBlock
  66 + completed:completedBlock];
117 } 67 }
118 68
119 -  
120 @end 69 @end
121 70
122 #endif 71 #endif
@@ -19,14 +19,6 @@ @@ -19,14 +19,6 @@
19 @interface MKAnnotationView (WebCache) 19 @interface MKAnnotationView (WebCache)
20 20
21 /** 21 /**
22 - * Get the current image URL.  
23 - *  
24 - * Note that because of the limitations of categories this property can get out of sync  
25 - * if you use setImage: directly.  
26 - */  
27 -- (nullable NSURL *)sd_imageURL;  
28 -  
29 -/**  
30 * Set the imageView `image` with an `url`. 22 * Set the imageView `image` with an `url`.
31 * 23 *
32 * The download is asynchronous and cached. 24 * The download is asynchronous and cached.
@@ -112,11 +104,6 @@ @@ -112,11 +104,6 @@
112 options:(SDWebImageOptions)options 104 options:(SDWebImageOptions)options
113 completed:(nullable SDExternalCompletionBlock)completedBlock; 105 completed:(nullable SDExternalCompletionBlock)completedBlock;
114 106
115 -/**  
116 - * Cancel the current download  
117 - */  
118 -- (void)sd_cancelCurrentImageLoad;  
119 -  
120 @end 107 @end
121 108
122 #endif 109 #endif
@@ -12,15 +12,10 @@ @@ -12,15 +12,10 @@
12 12
13 #import "objc/runtime.h" 13 #import "objc/runtime.h"
14 #import "UIView+WebCacheOperation.h" 14 #import "UIView+WebCacheOperation.h"
15 -  
16 -static char imageURLKey; 15 +#import "UIView+WebCache.h"
17 16
18 @implementation MKAnnotationView (WebCache) 17 @implementation MKAnnotationView (WebCache)
19 18
20 -- (nullable NSURL *)sd_imageURL {  
21 - return objc_getAssociatedObject(self, &imageURLKey);  
22 -}  
23 -  
24 - (void)sd_setImageWithURL:(nullable NSURL *)url { 19 - (void)sd_setImageWithURL:(nullable NSURL *)url {
25 [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil]; 20 [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil];
26 } 21 }
@@ -45,56 +40,16 @@ static char imageURLKey; @@ -45,56 +40,16 @@ static char imageURLKey;
45 placeholderImage:(nullable UIImage *)placeholder 40 placeholderImage:(nullable UIImage *)placeholder
46 options:(SDWebImageOptions)options 41 options:(SDWebImageOptions)options
47 completed:(nullable SDExternalCompletionBlock)completedBlock { 42 completed:(nullable SDExternalCompletionBlock)completedBlock {
48 - [self sd_cancelCurrentImageLoad];  
49 -  
50 - objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);  
51 - self.image = placeholder;  
52 -  
53 - if (url) {  
54 - __weak __typeof(self)wself = self;  
55 - id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {  
56 - if (!wself) return;  
57 - dispatch_main_sync_safe(^{  
58 - __strong MKAnnotationView *sself = wself;  
59 - if (!sself) return;  
60 - if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock) {  
61 - completedBlock(image, error, cacheType, url);  
62 - return;  
63 - } else if (image) {  
64 - wself.image = image;  
65 -#if SD_UIKIT  
66 - [wself setNeedsLayout];  
67 -#elif SD_MAC  
68 - [wself setNeedsLayout:YES];  
69 -#endif  
70 - } else {  
71 - if ((options & SDWebImageDelayPlaceholder)) {  
72 - wself.image = placeholder;  
73 -#if SD_UIKIT  
74 - [wself setNeedsLayout];  
75 -#elif SD_MAC  
76 - [wself setNeedsDisplay:YES];  
77 -#endif  
78 - }  
79 - }  
80 - if (completedBlock && finished) {  
81 - completedBlock(image, error, cacheType, url);  
82 - }  
83 - });  
84 - }];  
85 - [self sd_setImageLoadOperation:operation forKey:@"MKAnnotationViewImage"];  
86 - } else {  
87 - dispatch_main_async_safe(^{  
88 - NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];  
89 - if (completedBlock) {  
90 - completedBlock(nil, error, SDImageCacheTypeNone, url);  
91 - }  
92 - });  
93 - }  
94 -}  
95 -  
96 -- (void)sd_cancelCurrentImageLoad {  
97 - [self sd_cancelImageLoadOperationWithKey:@"MKAnnotationViewImage"]; 43 + __weak typeof(self)weakSelf = self;
  44 + [self sd_internalSetImageWithURL:url
  45 + placeholderImage:placeholder
  46 + options:options
  47 + operationKey:nil
  48 + setImageBlock:^(UIImage *image, NSData *imageData) {
  49 + weakSelf.image = image;
  50 + }
  51 + progress:nil
  52 + completed:completedBlock];
98 } 53 }
99 54
100 @end 55 @end
@@ -22,6 +22,8 @@ @@ -22,6 +22,8 @@
22 */ 22 */
23 - (nullable NSURL *)sd_currentImageURL; 23 - (nullable NSURL *)sd_currentImageURL;
24 24
  25 +#pragma mark - Image
  26 +
25 /** 27 /**
26 * Get the image URL for a control state. 28 * Get the image URL for a control state.
27 * 29 *
@@ -126,6 +128,8 @@ @@ -126,6 +128,8 @@
126 options:(SDWebImageOptions)options 128 options:(SDWebImageOptions)options
127 completed:(nullable SDExternalCompletionBlock)completedBlock; 129 completed:(nullable SDExternalCompletionBlock)completedBlock;
128 130
  131 +#pragma mark - Background image
  132 +
129 /** 133 /**
130 * Set the backgroundImageView `image` with an `url`. 134 * Set the backgroundImageView `image` with an `url`.
131 * 135 *
@@ -222,6 +226,8 @@ @@ -222,6 +226,8 @@
222 options:(SDWebImageOptions)options 226 options:(SDWebImageOptions)options
223 completed:(nullable SDExternalCompletionBlock)completedBlock; 227 completed:(nullable SDExternalCompletionBlock)completedBlock;
224 228
  229 +#pragma mark - Cancel
  230 +
225 /** 231 /**
226 * Cancel the current image download 232 * Cancel the current image download
227 */ 233 */
@@ -12,6 +12,7 @@ @@ -12,6 +12,7 @@
12 12
13 #import "objc/runtime.h" 13 #import "objc/runtime.h"
14 #import "UIView+WebCacheOperation.h" 14 #import "UIView+WebCacheOperation.h"
  15 +#import "UIView+WebCache.h"
15 16
16 static char imageURLStorageKey; 17 static char imageURLStorageKey;
17 18
@@ -33,6 +34,8 @@ typedef NSMutableDictionary<NSNumber *, NSURL *> SDStateImageURLDictionary; @@ -33,6 +34,8 @@ typedef NSMutableDictionary<NSNumber *, NSURL *> SDStateImageURLDictionary;
33 return self.imageURLStorage[@(state)]; 34 return self.imageURLStorage[@(state)];
34 } 35 }
35 36
  37 +#pragma mark - Image
  38 +
36 - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state { 39 - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state {
37 [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; 40 [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];
38 } 41 }
@@ -58,46 +61,27 @@ typedef NSMutableDictionary<NSNumber *, NSURL *> SDStateImageURLDictionary; @@ -58,46 +61,27 @@ typedef NSMutableDictionary<NSNumber *, NSURL *> SDStateImageURLDictionary;
58 placeholderImage:(nullable UIImage *)placeholder 61 placeholderImage:(nullable UIImage *)placeholder
59 options:(SDWebImageOptions)options 62 options:(SDWebImageOptions)options
60 completed:(nullable SDExternalCompletionBlock)completedBlock { 63 completed:(nullable SDExternalCompletionBlock)completedBlock {
61 - [self setImage:placeholder forState:state];  
62 - [self sd_cancelImageLoadForState:state];  
63 -  
64 if (!url) { 64 if (!url) {
65 [self.imageURLStorage removeObjectForKey:@(state)]; 65 [self.imageURLStorage removeObjectForKey:@(state)];
66 -  
67 - dispatch_main_async_safe(^{  
68 - if (completedBlock) {  
69 - NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];  
70 - completedBlock(nil, error, SDImageCacheTypeNone, url);  
71 - }  
72 - });  
73 -  
74 return; 66 return;
75 } 67 }
76 68
77 self.imageURLStorage[@(state)] = url; 69 self.imageURLStorage[@(state)] = url;
78 -  
79 - __weak __typeof(self)wself = self;  
80 - id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {  
81 - if (!wself) return;  
82 - dispatch_main_sync_safe(^{  
83 - __strong UIButton *sself = wself;  
84 - if (!sself) return;  
85 - if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)  
86 - {  
87 - completedBlock(image, error, cacheType, url);  
88 - return;  
89 - }  
90 - else if (image) {  
91 - [sself setImage:image forState:state];  
92 - }  
93 - if (completedBlock && finished) {  
94 - completedBlock(image, error, cacheType, url);  
95 - }  
96 - });  
97 - }];  
98 - [self sd_setImageLoadOperation:operation forState:state]; 70 +
  71 + __weak typeof(self)weakSelf = self;
  72 + [self sd_internalSetImageWithURL:url
  73 + placeholderImage:placeholder
  74 + options:options
  75 + operationKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]
  76 + setImageBlock:^(UIImage *image, NSData *imageData) {
  77 + [weakSelf setImage:image forState:state];
  78 + }
  79 + progress:nil
  80 + completed:completedBlock];
99 } 81 }
100 82
  83 +#pragma mark - Background image
  84 +
101 - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state { 85 - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state {
102 [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; 86 [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];
103 } 87 }
@@ -123,39 +107,23 @@ typedef NSMutableDictionary<NSNumber *, NSURL *> SDStateImageURLDictionary; @@ -123,39 +107,23 @@ typedef NSMutableDictionary<NSNumber *, NSURL *> SDStateImageURLDictionary;
123 placeholderImage:(nullable UIImage *)placeholder 107 placeholderImage:(nullable UIImage *)placeholder
124 options:(SDWebImageOptions)options 108 options:(SDWebImageOptions)options
125 completed:(nullable SDExternalCompletionBlock)completedBlock { 109 completed:(nullable SDExternalCompletionBlock)completedBlock {
126 - [self sd_cancelBackgroundImageLoadForState:state];  
127 -  
128 - [self setBackgroundImage:placeholder forState:state];  
129 -  
130 - if (url) {  
131 - __weak __typeof(self)wself = self;  
132 - id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {  
133 - if (!wself) return;  
134 - dispatch_main_sync_safe(^{  
135 - __strong UIButton *sself = wself;  
136 - if (!sself) return;  
137 - if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)  
138 - {  
139 - completedBlock(image, error, cacheType, url);  
140 - return;  
141 - }  
142 - else if (image) {  
143 - [sself setBackgroundImage:image forState:state];  
144 - }  
145 - if (completedBlock && finished) {  
146 - completedBlock(image, error, cacheType, url);  
147 - }  
148 - });  
149 - }];  
150 - [self sd_setBackgroundImageLoadOperation:operation forState:state];  
151 - } else {  
152 - dispatch_main_async_safe(^{  
153 - NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];  
154 - if (completedBlock) {  
155 - completedBlock(nil, error, SDImageCacheTypeNone, url);  
156 - }  
157 - }); 110 + if (!url) {
  111 + [self.imageURLStorage removeObjectForKey:@(state)];
  112 + return;
158 } 113 }
  114 +
  115 + self.imageURLStorage[@(state)] = url;
  116 +
  117 + __weak typeof(self)weakSelf = self;
  118 + [self sd_internalSetImageWithURL:url
  119 + placeholderImage:placeholder
  120 + options:options
  121 + operationKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]
  122 + setImageBlock:^(UIImage *image, NSData *imageData) {
  123 + [weakSelf setBackgroundImage:image forState:state];
  124 + }
  125 + progress:nil
  126 + completed:completedBlock];
159 } 127 }
160 128
161 - (void)sd_setImageLoadOperation:(id<SDWebImageOperation>)operation forState:(UIControlState)state { 129 - (void)sd_setImageLoadOperation:(id<SDWebImageOperation>)operation forState:(UIControlState)state {
@@ -176,8 +144,7 @@ typedef NSMutableDictionary<NSNumber *, NSURL *> SDStateImageURLDictionary; @@ -176,8 +144,7 @@ typedef NSMutableDictionary<NSNumber *, NSURL *> SDStateImageURLDictionary;
176 144
177 - (SDStateImageURLDictionary *)imageURLStorage { 145 - (SDStateImageURLDictionary *)imageURLStorage {
178 SDStateImageURLDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey); 146 SDStateImageURLDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey);
179 - if (!storage)  
180 - { 147 + if (!storage) {
181 storage = [NSMutableDictionary dictionary]; 148 storage = [NSMutableDictionary dictionary];
182 objc_setAssociatedObject(self, &imageURLStorageKey, storage, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 149 objc_setAssociatedObject(self, &imageURLStorageKey, storage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
183 } 150 }
@@ -88,11 +88,6 @@ @@ -88,11 +88,6 @@
88 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 88 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
89 completed:(nullable SDExternalCompletionBlock)completedBlock; 89 completed:(nullable SDExternalCompletionBlock)completedBlock;
90 90
91 -/**  
92 - * Cancel the current download  
93 - */  
94 -- (void)sd_cancelCurrentHighlightedImageLoad;  
95 -  
96 @end 91 @end
97 92
98 #endif 93 #endif
@@ -11,8 +11,7 @@ @@ -11,8 +11,7 @@
11 #if SD_UIKIT 11 #if SD_UIKIT
12 12
13 #import "UIView+WebCacheOperation.h" 13 #import "UIView+WebCacheOperation.h"
14 -  
15 -#define UIImageViewHighlightedWebCacheOperationKey @"highlightedImage" 14 +#import "UIView+WebCache.h"
16 15
17 @implementation UIImageView (HighlightedWebCache) 16 @implementation UIImageView (HighlightedWebCache)
18 17
@@ -36,41 +35,16 @@ @@ -36,41 +35,16 @@
36 options:(SDWebImageOptions)options 35 options:(SDWebImageOptions)options
37 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 36 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
38 completed:(nullable SDExternalCompletionBlock)completedBlock { 37 completed:(nullable SDExternalCompletionBlock)completedBlock {
39 - [self sd_cancelCurrentHighlightedImageLoad];  
40 -  
41 - if (url) {  
42 - __weak __typeof(self)wself = self;  
43 - id<SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {  
44 - if (!wself) return;  
45 - dispatch_main_sync_safe (^{  
46 - if (!wself) return;  
47 - if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)  
48 - {  
49 - completedBlock(image, error, cacheType, url);  
50 - return;  
51 - }  
52 - else if (image) {  
53 - wself.highlightedImage = image;  
54 - [wself setNeedsLayout];  
55 - }  
56 - if (completedBlock && finished) {  
57 - completedBlock(image, error, cacheType, url);  
58 - }  
59 - });  
60 - }];  
61 - [self sd_setImageLoadOperation:operation forKey:UIImageViewHighlightedWebCacheOperationKey];  
62 - } else {  
63 - dispatch_main_async_safe(^{  
64 - NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];  
65 - if (completedBlock) {  
66 - completedBlock(nil, error, SDImageCacheTypeNone, url);  
67 - }  
68 - });  
69 - }  
70 -}  
71 -  
72 -- (void)sd_cancelCurrentHighlightedImageLoad {  
73 - [self sd_cancelImageLoadOperationWithKey:UIImageViewHighlightedWebCacheOperationKey]; 38 + __weak typeof(self)weakSelf = self;
  39 + [self sd_internalSetImageWithURL:url
  40 + placeholderImage:nil
  41 + options:options
  42 + operationKey:@"UIImageViewImageOperationHighlighted"
  43 + setImageBlock:^(UIImage *image, NSData *imageData) {
  44 + weakSelf.highlightedImage = image;
  45 + }
  46 + progress:progressBlock
  47 + completed:completedBlock];
74 } 48 }
75 49
76 @end 50 @end
@@ -48,14 +48,6 @@ @@ -48,14 +48,6 @@
48 @interface UIImageView (WebCache) 48 @interface UIImageView (WebCache)
49 49
50 /** 50 /**
51 - * Get the current image URL.  
52 - *  
53 - * Note that because of the limitations of categories this property can get out of sync  
54 - * if you use setImage: directly.  
55 - */  
56 -- (nullable NSURL *)sd_imageURL;  
57 -  
58 -/**  
59 * Set the imageView `image` with an `url`. 51 * Set the imageView `image` with an `url`.
60 * 52 *
61 * The download is asynchronous and cached. 53 * The download is asynchronous and cached.
@@ -183,37 +175,18 @@ @@ -183,37 +175,18 @@
183 completed:(nullable SDExternalCompletionBlock)completedBlock; 175 completed:(nullable SDExternalCompletionBlock)completedBlock;
184 176
185 #if SD_UIKIT 177 #if SD_UIKIT
  178 +
  179 +#pragma mark - Animation of multiple images
  180 +
186 /** 181 /**
187 * Download an array of images and starts them in an animation loop 182 * Download an array of images and starts them in an animation loop
188 * 183 *
189 * @param arrayOfURLs An array of NSURL 184 * @param arrayOfURLs An array of NSURL
190 */ 185 */
191 - (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs; 186 - (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs;
192 -#endif  
193 -  
194 -/**  
195 - * Cancel the current download  
196 - */  
197 -- (void)sd_cancelCurrentImageLoad;  
198 187
199 -#if SD_UIKIT  
200 - (void)sd_cancelCurrentAnimationImagesLoad; 188 - (void)sd_cancelCurrentAnimationImagesLoad;
201 189
202 -/**  
203 - * Show activity UIActivityIndicatorView  
204 - */  
205 -- (void)setShowActivityIndicatorView:(BOOL)show;  
206 -  
207 -/**  
208 - * set desired UIActivityIndicatorViewStyle  
209 - *  
210 - * @param style The style of the UIActivityIndicatorView  
211 - */  
212 -- (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style;  
213 -  
214 -- (BOOL)showActivityIndicatorView;  
215 -- (void)addActivityIndicator;  
216 -- (void)removeActivityIndicator;  
217 #endif 190 #endif
218 191
219 @end 192 @end
@@ -12,13 +12,7 @@ @@ -12,13 +12,7 @@
12 12
13 #import "objc/runtime.h" 13 #import "objc/runtime.h"
14 #import "UIView+WebCacheOperation.h" 14 #import "UIView+WebCacheOperation.h"
15 -  
16 -static char imageURLKey;  
17 -#if SD_UIKIT  
18 -static char TAG_ACTIVITY_INDICATOR;  
19 -static char TAG_ACTIVITY_STYLE;  
20 -#endif  
21 -static char TAG_ACTIVITY_SHOW; 15 +#import "UIView+WebCache.h"
22 16
23 @implementation UIImageView (WebCache) 17 @implementation UIImageView (WebCache)
24 18
@@ -51,65 +45,13 @@ static char TAG_ACTIVITY_SHOW; @@ -51,65 +45,13 @@ static char TAG_ACTIVITY_SHOW;
51 options:(SDWebImageOptions)options 45 options:(SDWebImageOptions)options
52 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock 46 progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
53 completed:(nullable SDExternalCompletionBlock)completedBlock { 47 completed:(nullable SDExternalCompletionBlock)completedBlock {
54 - [self sd_cancelCurrentImageLoad];  
55 - objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);  
56 -  
57 - if (!(options & SDWebImageDelayPlaceholder)) {  
58 - dispatch_main_async_safe(^{  
59 - self.image = placeholder;  
60 - });  
61 - }  
62 -  
63 - if (url) {  
64 -  
65 - // check if activityView is enabled or not  
66 - if ([self showActivityIndicatorView]) {  
67 - [self addActivityIndicator];  
68 - }  
69 -  
70 - __weak __typeof(self)wself = self;  
71 - id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {  
72 - [wself removeActivityIndicator];  
73 - if (!wself) return;  
74 - dispatch_main_sync_safe(^{  
75 - if (!wself) return;  
76 - if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)  
77 - {  
78 - completedBlock(image, error, cacheType, url);  
79 - return;  
80 - }  
81 - else if (image) {  
82 - wself.image = image;  
83 -#if SD_UIKIT  
84 - [wself setNeedsLayout];  
85 -#elif SD_MAC  
86 - [wself setNeedsLayout:YES];  
87 -#endif  
88 - } else {  
89 - if ((options & SDWebImageDelayPlaceholder)) {  
90 - wself.image = placeholder;  
91 -#if SD_UIKIT  
92 - [wself setNeedsLayout];  
93 -#elif SD_MAC  
94 - [wself setNeedsLayout:YES];  
95 -#endif  
96 - }  
97 - }  
98 - if (completedBlock && finished) {  
99 - completedBlock(image, error, cacheType, url);  
100 - }  
101 - });  
102 - }];  
103 - [self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];  
104 - } else {  
105 - dispatch_main_async_safe(^{  
106 - [self removeActivityIndicator];  
107 - if (completedBlock) {  
108 - NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];  
109 - completedBlock(nil, error, SDImageCacheTypeNone, url);  
110 - }  
111 - });  
112 - } 48 + [self sd_internalSetImageWithURL:url
  49 + placeholderImage:placeholder
  50 + options:options
  51 + operationKey:nil
  52 + setImageBlock:nil
  53 + progress:progressBlock
  54 + completed:completedBlock];
113 } 55 }
114 56
115 - (void)sd_setImageWithPreviousCachedImageWithURL:(nullable NSURL *)url 57 - (void)sd_setImageWithPreviousCachedImageWithURL:(nullable NSURL *)url
@@ -123,11 +65,10 @@ static char TAG_ACTIVITY_SHOW; @@ -123,11 +65,10 @@ static char TAG_ACTIVITY_SHOW;
123 [self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock]; 65 [self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock];
124 } 66 }
125 67
126 -- (nullable NSURL *)sd_imageURL {  
127 - return objc_getAssociatedObject(self, &imageURLKey);  
128 -}  
129 -  
130 #if SD_UIKIT 68 #if SD_UIKIT
  69 +
  70 +#pragma mark - Animation of multiple images
  71 +
131 - (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs { 72 - (void)sd_setAnimationImagesWithURLs:(nonnull NSArray<NSURL *> *)arrayOfURLs {
132 [self sd_cancelCurrentAnimationImagesLoad]; 73 [self sd_cancelCurrentAnimationImagesLoad];
133 __weak __typeof(self)wself = self; 74 __weak __typeof(self)wself = self;
@@ -158,88 +99,12 @@ static char TAG_ACTIVITY_SHOW; @@ -158,88 +99,12 @@ static char TAG_ACTIVITY_SHOW;
158 99
159 [self sd_setImageLoadOperation:[operationsArray copy] forKey:@"UIImageViewAnimationImages"]; 100 [self sd_setImageLoadOperation:[operationsArray copy] forKey:@"UIImageViewAnimationImages"];
160 } 101 }
161 -#endif  
162 -  
163 -- (void)sd_cancelCurrentImageLoad {  
164 - [self sd_cancelImageLoadOperationWithKey:@"UIImageViewImageLoad"];  
165 -}  
166 102
167 -#if SD_UIKIT  
168 - (void)sd_cancelCurrentAnimationImagesLoad { 103 - (void)sd_cancelCurrentAnimationImagesLoad {
169 [self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"]; 104 [self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"];
170 } 105 }
171 #endif 106 #endif
172 107
173 -#pragma mark -  
174 -#if SD_UIKIT  
175 -- (UIActivityIndicatorView *)activityIndicator {  
176 - return (UIActivityIndicatorView *)objc_getAssociatedObject(self, &TAG_ACTIVITY_INDICATOR);  
177 -}  
178 -  
179 -- (void)setActivityIndicator:(UIActivityIndicatorView *)activityIndicator {  
180 - objc_setAssociatedObject(self, &TAG_ACTIVITY_INDICATOR, activityIndicator, OBJC_ASSOCIATION_RETAIN);  
181 -}  
182 -#endif  
183 -  
184 -- (void)setShowActivityIndicatorView:(BOOL)show {  
185 - objc_setAssociatedObject(self, &TAG_ACTIVITY_SHOW, @(show), OBJC_ASSOCIATION_RETAIN);  
186 -}  
187 -  
188 -- (BOOL)showActivityIndicatorView {  
189 - return [objc_getAssociatedObject(self, &TAG_ACTIVITY_SHOW) boolValue];  
190 -}  
191 -  
192 -#if SD_UIKIT  
193 -- (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style{  
194 - objc_setAssociatedObject(self, &TAG_ACTIVITY_STYLE, [NSNumber numberWithInt:style], OBJC_ASSOCIATION_RETAIN);  
195 -}  
196 -  
197 -- (int)getIndicatorStyle{  
198 - return [objc_getAssociatedObject(self, &TAG_ACTIVITY_STYLE) intValue];  
199 -}  
200 -#endif  
201 -  
202 -- (void)addActivityIndicator {  
203 -#if SD_UIKIT  
204 - if (!self.activityIndicator) {  
205 - self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:[self getIndicatorStyle]];  
206 - self.activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;  
207 -  
208 - dispatch_main_async_safe(^{  
209 - [self addSubview:self.activityIndicator];  
210 -  
211 - [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator  
212 - attribute:NSLayoutAttributeCenterX  
213 - relatedBy:NSLayoutRelationEqual  
214 - toItem:self  
215 - attribute:NSLayoutAttributeCenterX  
216 - multiplier:1.0  
217 - constant:0.0]];  
218 - [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator  
219 - attribute:NSLayoutAttributeCenterY  
220 - relatedBy:NSLayoutRelationEqual  
221 - toItem:self  
222 - attribute:NSLayoutAttributeCenterY  
223 - multiplier:1.0  
224 - constant:0.0]];  
225 - });  
226 - }  
227 -  
228 - dispatch_main_async_safe(^{  
229 - [self.activityIndicator startAnimating];  
230 - });  
231 -#endif  
232 -}  
233 -  
234 -- (void)removeActivityIndicator {  
235 -#if SD_UIKIT  
236 - if (self.activityIndicator) {  
237 - [self.activityIndicator removeFromSuperview];  
238 - self.activityIndicator = nil;  
239 - }  
240 -#endif  
241 -}  
242 -  
243 @end 108 @end
244 109
245 #endif 110 #endif
  1 +/*
  2 + * This file is part of the SDWebImage package.
  3 + * (c) Olivier Poitrey <rs@dailymotion.com>
  4 + *
  5 + * For the full copyright and license information, please view the LICENSE
  6 + * file that was distributed with this source code.
  7 + */
  8 +
  9 +#import "SDWebImageCompat.h"
  10 +
  11 +#if SD_UIKIT || SD_MAC
  12 +
  13 +#import "SDWebImageManager.h"
  14 +
  15 +typedef void(^SDSetImageBlock)(UIImage * _Nullable image, NSData * _Nullable imageData);
  16 +
  17 +@interface UIView (WebCache)
  18 +
  19 +/**
  20 + * Get the current image URL.
  21 + *
  22 + * Note that because of the limitations of categories this property can get out of sync
  23 + * if you use setImage: directly.
  24 + */
  25 +- (nullable NSURL *)sd_imageURL;
  26 +
  27 +/**
  28 + * Set the imageView `image` with an `url` and optionally a placeholder image.
  29 + *
  30 + * The download is asynchronous and cached.
  31 + *
  32 + * @param url The url for the image.
  33 + * @param placeholder The image to be set initially, until the image request finishes.
  34 + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
  35 + * @param operationKey A string to be used as the operation key. If nil, will use the class name
  36 + * @param setImageBlock Block used for custom set image code
  37 + * @param progressBlock A block called while image is downloading
  38 + * @param completedBlock A block called when operation has been completed. This block has no return value
  39 + * and takes the requested UIImage as first parameter. In case of error the image parameter
  40 + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
  41 + * indicating if the image was retrieved from the local cache or from the network.
  42 + * The fourth parameter is the original image url.
  43 + */
  44 +- (void)sd_internalSetImageWithURL:(nullable NSURL *)url
  45 + placeholderImage:(nullable UIImage *)placeholder
  46 + options:(SDWebImageOptions)options
  47 + operationKey:(nullable NSString *)operationKey
  48 + setImageBlock:(nullable SDSetImageBlock)setImageBlock
  49 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  50 + completed:(nullable SDExternalCompletionBlock)completedBlock;
  51 +
  52 +/**
  53 + * Cancel the current download
  54 + */
  55 +- (void)sd_cancelCurrentImageLoad;
  56 +
  57 +#if SD_UIKIT
  58 +
  59 +#pragma mark - Activity indicator
  60 +
  61 +/**
  62 + * Show activity UIActivityIndicatorView
  63 + */
  64 +- (void)setShowActivityIndicatorView:(BOOL)show;
  65 +
  66 +/**
  67 + * set desired UIActivityIndicatorViewStyle
  68 + *
  69 + * @param style The style of the UIActivityIndicatorView
  70 + */
  71 +- (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style;
  72 +
  73 +- (BOOL)showActivityIndicatorView;
  74 +- (void)addActivityIndicator;
  75 +- (void)removeActivityIndicator;
  76 +
  77 +#endif
  78 +
  79 +@end
  80 +
  81 +#endif
  1 +/*
  2 + * This file is part of the SDWebImage package.
  3 + * (c) Olivier Poitrey <rs@dailymotion.com>
  4 + *
  5 + * For the full copyright and license information, please view the LICENSE
  6 + * file that was distributed with this source code.
  7 + */
  8 +
  9 +#import "UIView+WebCache.h"
  10 +
  11 +#if SD_UIKIT || SD_MAC
  12 +
  13 +#import "objc/runtime.h"
  14 +#import "UIView+WebCacheOperation.h"
  15 +
  16 +static char imageURLKey;
  17 +
  18 +#if SD_UIKIT
  19 +static char TAG_ACTIVITY_INDICATOR;
  20 +static char TAG_ACTIVITY_STYLE;
  21 +#endif
  22 +static char TAG_ACTIVITY_SHOW;
  23 +
  24 +@implementation UIView (WebCache)
  25 +
  26 +- (nullable NSURL *)sd_imageURL {
  27 + return objc_getAssociatedObject(self, &imageURLKey);
  28 +}
  29 +
  30 +- (void)sd_internalSetImageWithURL:(nullable NSURL *)url
  31 + placeholderImage:(nullable UIImage *)placeholder
  32 + options:(SDWebImageOptions)options
  33 + operationKey:(nullable NSString *)operationKey
  34 + setImageBlock:(nullable SDSetImageBlock)setImageBlock
  35 + progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
  36 + completed:(nullable SDExternalCompletionBlock)completedBlock {
  37 + NSString *validOperationKey = operationKey ?: NSStringFromClass([self class]);
  38 + [self sd_cancelImageLoadOperationWithKey:validOperationKey];
  39 + objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  40 +
  41 + if (!(options & SDWebImageDelayPlaceholder)) {
  42 + dispatch_main_async_safe(^{
  43 + [self sd_setImage:placeholder imageData:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock];
  44 + });
  45 + }
  46 +
  47 + if (url) {
  48 + // check if activityView is enabled or not
  49 + if ([self showActivityIndicatorView]) {
  50 + [self addActivityIndicator];
  51 + }
  52 +
  53 + __weak __typeof(self)wself = self;
  54 + id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager loadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSData *data, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
  55 + __strong __typeof (wself) sself = wself;
  56 + [sself removeActivityIndicator];
  57 + if (!sself) {
  58 + return;
  59 + }
  60 + dispatch_main_sync_safe(^{
  61 + if (!sself) {
  62 + return;
  63 + }
  64 + if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock) {
  65 + completedBlock(image, error, cacheType, url);
  66 + return;
  67 + } else if (image) {
  68 + [sself sd_setImage:image imageData:data basedOnClassOrViaCustomSetImageBlock:setImageBlock];
  69 + [sself sd_setNeedsLayout];
  70 + } else {
  71 + if ((options & SDWebImageDelayPlaceholder)) {
  72 + [sself sd_setImage:placeholder imageData:nil basedOnClassOrViaCustomSetImageBlock:setImageBlock];
  73 + [sself sd_setNeedsLayout];
  74 + }
  75 + }
  76 + if (completedBlock && finished) {
  77 + completedBlock(image, error, cacheType, url);
  78 + }
  79 + });
  80 + }];
  81 + [self sd_setImageLoadOperation:operation forKey:validOperationKey];
  82 + } else {
  83 + dispatch_main_async_safe(^{
  84 + [self removeActivityIndicator];
  85 + if (completedBlock) {
  86 + NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
  87 + completedBlock(nil, error, SDImageCacheTypeNone, url);
  88 + }
  89 + });
  90 + }
  91 +}
  92 +
  93 +- (void)sd_cancelCurrentImageLoad {
  94 + [self sd_cancelImageLoadOperationWithKey:NSStringFromClass([self class])];
  95 +}
  96 +
  97 +- (void)sd_setImage:(UIImage *)image imageData:(NSData *)imageData basedOnClassOrViaCustomSetImageBlock:(SDSetImageBlock)setImageBlock {
  98 + if (setImageBlock) {
  99 + setImageBlock(image, imageData);
  100 + } else if ([self isKindOfClass:[UIImageView class]]) {
  101 + UIImageView *imageView = (UIImageView *)self;
  102 + imageView.image = image;
  103 + } else if ([self isKindOfClass:[UIButton class]]) {
  104 + UIButton *button = (UIButton *)self;
  105 + [button setImage:image forState:UIControlStateNormal];
  106 + }
  107 +}
  108 +
  109 +- (void)sd_setNeedsLayout {
  110 +#if SD_UIKIT
  111 + [self setNeedsLayout];
  112 +#elif SD_MAC
  113 + [self setNeedsLayout:YES];
  114 +#endif
  115 +}
  116 +
  117 +#pragma mark - Activity indicator
  118 +
  119 +#pragma mark -
  120 +#if SD_UIKIT
  121 +- (UIActivityIndicatorView *)activityIndicator {
  122 + return (UIActivityIndicatorView *)objc_getAssociatedObject(self, &TAG_ACTIVITY_INDICATOR);
  123 +}
  124 +
  125 +- (void)setActivityIndicator:(UIActivityIndicatorView *)activityIndicator {
  126 + objc_setAssociatedObject(self, &TAG_ACTIVITY_INDICATOR, activityIndicator, OBJC_ASSOCIATION_RETAIN);
  127 +}
  128 +#endif
  129 +
  130 +- (void)setShowActivityIndicatorView:(BOOL)show {
  131 + objc_setAssociatedObject(self, &TAG_ACTIVITY_SHOW, @(show), OBJC_ASSOCIATION_RETAIN);
  132 +}
  133 +
  134 +- (BOOL)showActivityIndicatorView {
  135 + return [objc_getAssociatedObject(self, &TAG_ACTIVITY_SHOW) boolValue];
  136 +}
  137 +
  138 +#if SD_UIKIT
  139 +- (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style{
  140 + objc_setAssociatedObject(self, &TAG_ACTIVITY_STYLE, [NSNumber numberWithInt:style], OBJC_ASSOCIATION_RETAIN);
  141 +}
  142 +
  143 +- (int)getIndicatorStyle{
  144 + return [objc_getAssociatedObject(self, &TAG_ACTIVITY_STYLE) intValue];
  145 +}
  146 +#endif
  147 +
  148 +- (void)addActivityIndicator {
  149 +#if SD_UIKIT
  150 + if (!self.activityIndicator) {
  151 + self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:[self getIndicatorStyle]];
  152 + self.activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;
  153 +
  154 + dispatch_main_async_safe(^{
  155 + [self addSubview:self.activityIndicator];
  156 +
  157 + [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator
  158 + attribute:NSLayoutAttributeCenterX
  159 + relatedBy:NSLayoutRelationEqual
  160 + toItem:self
  161 + attribute:NSLayoutAttributeCenterX
  162 + multiplier:1.0
  163 + constant:0.0]];
  164 + [self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator
  165 + attribute:NSLayoutAttributeCenterY
  166 + relatedBy:NSLayoutRelationEqual
  167 + toItem:self
  168 + attribute:NSLayoutAttributeCenterY
  169 + multiplier:1.0
  170 + constant:0.0]];
  171 + });
  172 + }
  173 +
  174 + dispatch_main_async_safe(^{
  175 + [self.activityIndicator startAnimating];
  176 + });
  177 +#endif
  178 +}
  179 +
  180 +- (void)removeActivityIndicator {
  181 +#if SD_UIKIT
  182 + if (self.activityIndicator) {
  183 + [self.activityIndicator removeFromSuperview];
  184 + self.activityIndicator = nil;
  185 + }
  186 +#endif
  187 +}
  188 +
  189 +@end
  190 +
  191 +#endif