Kaynağa Gözat

Keep track on placeholder

Or there might be a chance that the prepended view not get removed.
onevcat 8 yıl önce
ebeveyn
işleme
8f169b2d3f

+ 2 - 1
Demo/Kingfisher-Demo/MyCustomPlaceholder.swift

@@ -24,8 +24,9 @@
 //  THE SOFTWARE.
 
 import UIKit
+import Kingfisher
 
-class MyCustomPlaceholder : UIView {
+class MyCustomPlaceholder : UIView, Placeholder {
     override func draw(_ rect: CGRect) {
         let path = UIBezierPath(ovalIn: rect)
         UIColor.red.setFill()

+ 27 - 6
Sources/ImageView+Kingfisher.swift

@@ -61,16 +61,17 @@ extension Kingfisher where Base: ImageView {
                          completionHandler: CompletionHandler? = nil) -> RetrieveImageTask
     {
         guard let resource = resource else {
-            placeholder?.add(to: self.base)
+            self.placeholder = placeholder
             setWebURL(nil)
             completionHandler?(nil, nil, .none, nil)
             return .empty
         }
         
         var options = KingfisherManager.shared.defaultOptions + (options ?? KingfisherEmptyOptionsInfo)
+        let noImageOrPlaceholderSet = base.image == nil && self.placeholder == nil
         
-        if !options.keepCurrentImageWhileLoading || base.image == nil {
-            placeholder?.add(to: self.base)
+        if !options.keepCurrentImageWhileLoading || noImageOrPlaceholderSet { // Always set placeholder while there is no image/placehoer yet.
+            self.placeholder = placeholder
         }
 
         let maybeIndicator = indicator
@@ -110,7 +111,7 @@ extension Kingfisher where Base: ImageView {
                     guard let transitionItem = options.lastMatchIgnoringAssociatedValue(.transition(.none)),
                         case .transition(let transition) = transitionItem, ( options.forceTransition || cacheType == .none) else
                     {
-                        placeholder?.remove(from: strongBase)
+                        self.placeholder = nil
                         strongBase.image = image
                         completionHandler?(image, error, cacheType, imageURL)
                         return
@@ -121,8 +122,7 @@ extension Kingfisher where Base: ImageView {
                                           animations: { maybeIndicator?.stopAnimatingView() },
                                           completion: { _ in
 
-                                            placeholder?.remove(from: strongBase)
-
+                                            self.placeholder = nil
                                             UIView.transition(with: strongBase, duration: transition.duration,
                                                               options: [transition.animationOptions, .allowUserInteraction],
                                                               animations: {
@@ -156,6 +156,7 @@ extension Kingfisher where Base: ImageView {
 private var lastURLKey: Void?
 private var indicatorKey: Void?
 private var indicatorTypeKey: Void?
+private var placeholderKey: Void?
 private var imageTaskKey: Void?
 
 extension Kingfisher where Base: ImageView {
@@ -229,6 +230,26 @@ extension Kingfisher where Base: ImageView {
     fileprivate func setImageTask(_ task: RetrieveImageTask?) {
         objc_setAssociatedObject(base, &imageTaskKey, task, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
     }
+    
+    public fileprivate(set) var placeholder: Placeholder? {
+        get {
+            return (objc_getAssociatedObject(base, &placeholderKey) as? Box<Placeholder?>)?.value
+        }
+        
+        set {
+            if let previousPlaceholder = placeholder {
+                previousPlaceholder.remove(from: base)
+            }
+            
+            if let newPlaceholder = newValue {
+                newPlaceholder.add(to: base)
+            } else {
+                base.image = nil
+            }
+            
+            objc_setAssociatedObject(base, &placeholderKey, Box(value: newValue), .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
+        }
+    }
 }
 
 

+ 4 - 2
Sources/Placeholder.swift

@@ -35,12 +35,14 @@ public protocol Placeholder {
     func remove(from imageView: ImageView)
 }
 
-extension Image: Placeholder {
+extension Placeholder where Self: Image {
     public func add(to imageView: ImageView) { imageView.image = self }
     public func remove(from imageView: ImageView) { imageView.image = nil }
 }
 
-extension UIView: Placeholder {
+extension Image: Placeholder {}
+
+extension Placeholder where Self: UIView {
     public func add(to imageView: ImageView) {
         imageView.addSubview(self)