Browse Source

Support for transition

onevcat 10 years ago
parent
commit
ec50fa4dcc

+ 10 - 6
Kingfisher-Demo/ViewController.swift

@@ -28,7 +28,7 @@ import UIKit
 import Kingfisher
 
 class ViewController: UICollectionViewController {
-
+    
     override func viewDidLoad() {
         super.viewDidLoad()
         // Do any additional setup after loading the view, typically from a nib.
@@ -57,14 +57,18 @@ extension ViewController {
     
     override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
         let cell = collectionView.dequeueReusableCellWithReuseIdentifier("collectionViewCell", forIndexPath: indexPath) as! CollectionViewCell
+        
         cell.cellImageView.kf_showIndicatorWhenLoading = true
         
         let URL = NSURL(string: "https://raw.githubusercontent.com/onevcat/Kingfisher/master/images/kingfisher-\(indexPath.row + 1).jpg")!
-        cell.cellImageView.kf_setImageWithResource(Resource(downloadURL: URL), placeholderImage: nil, optionsInfo: nil, progressBlock: { (receivedSize, totalSize) -> () in
-            print("\(indexPath.row + 1): \(receivedSize)/\(totalSize)")
-        }) { (image, error, cacheType, imageURL) -> () in
-            print("\(indexPath.row + 1): Finished")
-        }
+        
+        cell.cellImageView.kf_setImageWithURL(URL, placeholderImage: nil,
+                                                        optionsInfo: [.Transition: ImageTransition.Fade(1)],
+                                                      progressBlock: { (receivedSize, totalSize) -> () in
+                                                          print("\(indexPath.row + 1): \(receivedSize)/\(totalSize)")
+                                                      }) { (image, error, cacheType, imageURL) -> () in
+                                                          print("\(indexPath.row + 1): Finished")
+                                                      }
         return cell
     }
 }

+ 4 - 0
Kingfisher.xcodeproj/project.pbxproj

@@ -18,6 +18,7 @@
 		4BAFBA3D1AD671E400FB0300 /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BAFBA3C1AD671E400FB0300 /* CollectionViewCell.swift */; };
 		4BBA04C21AD795C500A5CF82 /* ImageDownloaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBA04C11AD795C500A5CF82 /* ImageDownloaderTests.swift */; };
 		4BBA04C41AD7986100A5CF82 /* KingfisherTestHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBA04C31AD7986100A5CF82 /* KingfisherTestHelper.swift */; };
+		D11250C11BAC4B6300B986EF /* ImageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = D11250C01BAC4B6300B986EF /* ImageTransition.swift */; settings = {ASSET_TAGS = (); }; };
 		D151E72B1AD3C48D004FD4AE /* UIImage+Decode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D151E72A1AD3C48D004FD4AE /* UIImage+Decode.swift */; };
 		D166E4CD1B73820700B129E3 /* UIImage+Normalize.swift in Sources */ = {isa = PBXBuildFile; fileRef = D166E4CC1B73820700B129E3 /* UIImage+Normalize.swift */; };
 		D1ED2D111AD2CFA600CFC3EB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1ED2D101AD2CFA600CFC3EB /* AppDelegate.swift */; };
@@ -100,6 +101,7 @@
 		4BBA04C31AD7986100A5CF82 /* KingfisherTestHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KingfisherTestHelper.swift; sourceTree = "<group>"; };
 		A8D69912DD16C2942EB1F40E /* Pods-KingfisherTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-KingfisherTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-KingfisherTests/Pods-KingfisherTests.release.xcconfig"; sourceTree = "<group>"; };
 		A9E621E297FEFAD35D39C34E /* libPods-KingfisherTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-KingfisherTests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+		D11250C01BAC4B6300B986EF /* ImageTransition.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageTransition.swift; sourceTree = "<group>"; };
 		D151E72A1AD3C48D004FD4AE /* UIImage+Decode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Decode.swift"; sourceTree = "<group>"; };
 		D166E4CC1B73820700B129E3 /* UIImage+Normalize.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Normalize.swift"; sourceTree = "<group>"; };
 		D1ED2D0B1AD2CFA600CFC3EB /* Kingfisher-Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Kingfisher-Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -218,6 +220,7 @@
 				D1ED2D581AD2D0F900CFC3EB /* ImageDownloader.swift */,
 				D1ED2D591AD2D0F900CFC3EB /* KingfisherManager.swift */,
 				D1ED2D5A1AD2D0F900CFC3EB /* KingfisherOptions.swift */,
+				D11250C01BAC4B6300B986EF /* ImageTransition.swift */,
 				4B412CA41AE8A2F9008D530A /* KingfisherOptionsInfo.swift */,
 				4B2C4DF71B7D7ACD000912CA /* Resource.swift */,
 				D1ED2D371AD2D09F00CFC3EB /* Supporting Files */,
@@ -465,6 +468,7 @@
 				4B412CA51AE8A2F9008D530A /* KingfisherOptionsInfo.swift in Sources */,
 				4B2C4DF81B7D7ACD000912CA /* Resource.swift in Sources */,
 				D1ED2D601AD2D0F900CFC3EB /* KingfisherOptions.swift in Sources */,
+				D11250C11BAC4B6300B986EF /* ImageTransition.swift in Sources */,
 				D151E72B1AD3C48D004FD4AE /* UIImage+Decode.swift in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;

+ 85 - 0
Kingfisher/ImageTransition.swift

@@ -0,0 +1,85 @@
+//
+//  ImageTransition.swift
+//  Kingfisher
+//
+//  Created by Wei Wang on 15/9/18.
+//
+//  Copyright (c) 2015 Wei Wang <onevcat@gmail.com>
+//
+//  Permission is hereby granted, free of charge, to any person obtaining a copy
+//  of this software and associated documentation files (the "Software"), to deal
+//  in the Software without restriction, including without limitation the rights
+//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+//  copies of the Software, and to permit persons to whom the Software is
+//  furnished to do so, subject to the following conditions:
+//
+//  The above copyright notice and this permission notice shall be included in
+//  all copies or substantial portions of the Software.
+//
+//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+//  THE SOFTWARE.
+
+import Foundation
+
+public enum ImageTransition {
+    case None
+    case Fade(NSTimeInterval)
+
+    case FlipFromLeft(NSTimeInterval)
+    case FlipFromRight(NSTimeInterval)
+    case FlipFromTop(NSTimeInterval)
+    case FlipFromBottom(NSTimeInterval)
+    
+    case Custom(duration: NSTimeInterval,
+                 options: UIViewAnimationOptions,
+              animations: ((UIImageView, UIImage) -> Void)?,
+              completion: ((Bool) -> Void)?)
+    
+    var duration: NSTimeInterval {
+        switch self {
+        case .None:                          return 0
+        case .Fade(let duration):            return duration
+            
+        case .FlipFromLeft(let duration):    return duration
+        case .FlipFromRight(let duration):   return duration
+        case .FlipFromTop(let duration):     return duration
+        case .FlipFromBottom(let duration):  return duration
+            
+        case .Custom(let duration, _, _, _): return duration
+        }
+    }
+    
+    var animationOptions: UIViewAnimationOptions {
+        switch self {
+        case .None:                         return .TransitionNone
+        case .Fade(_):                      return .TransitionCrossDissolve
+            
+        case .FlipFromLeft(_):              return .TransitionFlipFromLeft
+        case .FlipFromRight(_):             return .TransitionFlipFromRight
+        case .FlipFromTop(_):               return .TransitionFlipFromTop
+        case .FlipFromBottom(_):            return .TransitionFlipFromBottom
+            
+        case .Custom(_, let options, _, _): return options
+        }
+    }
+    
+    var animations: ((UIImageView, UIImage) -> Void)? {
+        switch self {
+        case .Custom(_, _, let animations, _): return animations
+        default: return {$0.image = $1}
+        }
+    }
+    
+    var completion: ((Bool) -> Void)? {
+        switch self {
+        case .Custom(_, _, _, let completion): return completion
+        default: return nil
+        }
+    }
+}
+

+ 1 - 0
Kingfisher/KingfisherOptionsInfo.swift

@@ -42,4 +42,5 @@ public enum KingfisherOptionsInfoKey {
     case Options
     case TargetCache
     case Downloader
+    case Transition
 }

+ 15 - 2
Kingfisher/UIImageView+Kingfisher.swift

@@ -197,8 +197,21 @@ public extension UIImageView {
             }, completionHandler: {[weak self] (image, error, cacheType, imageURL) -> () in
                 dispatch_async(dispatch_get_main_queue(), { () -> Void in
                     if let sSelf = self where imageURL == sSelf.kf_webURL && image != nil {
-                        sSelf.image = image;
-                        indicator?.stopAnimating()
+                        if let transition = optionsInfo?[.Transition] as? ImageTransition {
+                            UIView.transitionWithView(sSelf, duration: 0.0, options: [], animations: { () -> Void in
+                                indicator?.stopAnimating()
+                                }, completion: { (finished) -> Void in
+                                    UIView.transitionWithView(sSelf, duration: transition.duration,
+                                        options: transition.animationOptions, animations:
+                                        { () -> Void in
+                                            transition.animations?(sSelf, image!)
+                                        }, completion: transition.completion)
+                            })
+                        } else {
+                            indicator?.stopAnimating()
+                            sSelf.image = image;
+                        }
+                        
                     }
                     
                     completionHandler?(image: image, error: error, cacheType: cacheType, imageURL: imageURL)