UIButton+WebCache.m 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. #import "UIButton+WebCache.h"
  9. #if SD_UIKIT
  10. #import "objc/runtime.h"
  11. #import "UIView+WebCacheOperation.h"
  12. #import "UIView+WebCache.h"
  13. static char imageURLStorageKey;
  14. typedef NSMutableDictionary<NSString *, NSURL *> SDStateImageURLDictionary;
  15. static inline NSString * imageURLKeyForState(UIControlState state) {
  16. return [NSString stringWithFormat:@"image_%lu", (unsigned long)state];
  17. }
  18. static inline NSString * backgroundImageURLKeyForState(UIControlState state) {
  19. return [NSString stringWithFormat:@"backgroundImage_%lu", (unsigned long)state];
  20. }
  21. @implementation UIButton (WebCache)
  22. #pragma mark - Image
  23. - (nullable NSURL *)sd_currentImageURL {
  24. NSURL *url = self.imageURLStorage[imageURLKeyForState(self.state)];
  25. if (!url) {
  26. url = self.imageURLStorage[imageURLKeyForState(UIControlStateNormal)];
  27. }
  28. return url;
  29. }
  30. - (nullable NSURL *)sd_imageURLForState:(UIControlState)state {
  31. return self.imageURLStorage[imageURLKeyForState(state)];
  32. }
  33. - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state {
  34. [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];
  35. }
  36. - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder {
  37. [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil];
  38. }
  39. - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {
  40. [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil];
  41. }
  42. - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state completed:(nullable SDExternalCompletionBlock)completedBlock {
  43. [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock];
  44. }
  45. - (void)sd_setImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {
  46. [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock];
  47. }
  48. - (void)sd_setImageWithURL:(nullable NSURL *)url
  49. forState:(UIControlState)state
  50. placeholderImage:(nullable UIImage *)placeholder
  51. options:(SDWebImageOptions)options
  52. completed:(nullable SDExternalCompletionBlock)completedBlock {
  53. if (!url) {
  54. [self.imageURLStorage removeObjectForKey:imageURLKeyForState(state)];
  55. return;
  56. }
  57. self.imageURLStorage[imageURLKeyForState(state)] = url;
  58. __weak typeof(self)weakSelf = self;
  59. [self sd_internalSetImageWithURL:url
  60. placeholderImage:placeholder
  61. options:options
  62. operationKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]
  63. setImageBlock:^(UIImage *image, NSData *imageData) {
  64. [weakSelf setImage:image forState:state];
  65. }
  66. progress:nil
  67. completed:completedBlock];
  68. }
  69. #pragma mark - Background image
  70. - (nullable NSURL *)sd_currentBackgroundImageURL {
  71. NSURL *url = self.imageURLStorage[backgroundImageURLKeyForState(self.state)];
  72. if (!url) {
  73. url = self.imageURLStorage[backgroundImageURLKeyForState(UIControlStateNormal)];
  74. }
  75. return url;
  76. }
  77. - (nullable NSURL *)sd_backgroundImageURLForState:(UIControlState)state {
  78. return self.imageURLStorage[backgroundImageURLKeyForState(state)];
  79. }
  80. - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state {
  81. [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];
  82. }
  83. - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder {
  84. [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil];
  85. }
  86. - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {
  87. [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil];
  88. }
  89. - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state completed:(nullable SDExternalCompletionBlock)completedBlock {
  90. [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock];
  91. }
  92. - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url forState:(UIControlState)state placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {
  93. [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock];
  94. }
  95. - (void)sd_setBackgroundImageWithURL:(nullable NSURL *)url
  96. forState:(UIControlState)state
  97. placeholderImage:(nullable UIImage *)placeholder
  98. options:(SDWebImageOptions)options
  99. completed:(nullable SDExternalCompletionBlock)completedBlock {
  100. if (!url) {
  101. [self.imageURLStorage removeObjectForKey:backgroundImageURLKeyForState(state)];
  102. return;
  103. }
  104. self.imageURLStorage[backgroundImageURLKeyForState(state)] = url;
  105. __weak typeof(self)weakSelf = self;
  106. [self sd_internalSetImageWithURL:url
  107. placeholderImage:placeholder
  108. options:options
  109. operationKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]
  110. setImageBlock:^(UIImage *image, NSData *imageData) {
  111. [weakSelf setBackgroundImage:image forState:state];
  112. }
  113. progress:nil
  114. completed:completedBlock];
  115. }
  116. - (void)sd_setImageLoadOperation:(id<SDWebImageOperation>)operation forState:(UIControlState)state {
  117. [self sd_setImageLoadOperation:operation forKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]];
  118. }
  119. - (void)sd_cancelImageLoadForState:(UIControlState)state {
  120. [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]];
  121. }
  122. - (void)sd_setBackgroundImageLoadOperation:(id<SDWebImageOperation>)operation forState:(UIControlState)state {
  123. [self sd_setImageLoadOperation:operation forKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]];
  124. }
  125. - (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state {
  126. [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]];
  127. }
  128. - (SDStateImageURLDictionary *)imageURLStorage {
  129. SDStateImageURLDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey);
  130. if (!storage) {
  131. storage = [NSMutableDictionary dictionary];
  132. objc_setAssociatedObject(self, &imageURLStorageKey, storage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  133. }
  134. return storage;
  135. }
  136. @end
  137. #endif