├── JLPhotoBrowser.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ ├── XBS.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ ├── liao.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── zhangtianlong.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── XBS.xcuserdatad │ └── xcschemes │ │ ├── JLPhotoBrowser.xcscheme │ │ └── xcschememanagement.plist │ ├── liao.xcuserdatad │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ │ ├── JLPhotoBrowser.xcscheme │ │ └── xcschememanagement.plist │ └── zhangtianlong.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── Copy of JLPhotoBrowser.xcscheme │ ├── JLPhotoBrowser.xcscheme │ └── xcschememanagement.plist ├── JLPhotoBrowser ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Classes │ ├── JLAlbum │ │ ├── JLCommon │ │ │ ├── JLCommon.h │ │ │ ├── JLReturnImageDelegate.h │ │ │ └── JLSelectedPhotoDelegate.h │ │ ├── JLControllers │ │ │ ├── JLALAssetGroupViewController.h │ │ │ ├── JLALAssetGroupViewController.m │ │ │ ├── JLBrowserViewController.h │ │ │ ├── JLBrowserViewController.m │ │ │ ├── JLNavigationController.h │ │ │ ├── JLNavigationController.m │ │ │ ├── JLThumbnailViewController.h │ │ │ └── JLThumbnailViewController.m │ │ ├── JLCotegory │ │ │ ├── ALAsset+Associate.h │ │ │ ├── ALAsset+Associate.m │ │ │ ├── UIImage+Extend.h │ │ │ ├── UIImage+Extend.m │ │ │ ├── UIView+Animation.h │ │ │ └── UIView+Animation.m │ │ ├── JLImages │ │ │ ├── camera_image_capture_badge@2x.png │ │ │ ├── camera_image_capture_badge@3x.png │ │ │ ├── compose_guide_check_box_default@2x.png │ │ │ ├── compose_guide_check_box_default@3x.png │ │ │ ├── compose_guide_check_box_right@2x.png │ │ │ ├── compose_guide_check_box_right@3x.png │ │ │ ├── navigationbar_back_dark@2x.png │ │ │ ├── navigationbar_back_dark@3x.png │ │ │ ├── navigationbar_back_withtext@2x.png │ │ │ └── navigationbar_back_withtext@3x.png │ │ ├── JLModels │ │ │ ├── JLAssetGroup.h │ │ │ ├── JLAssetGroup.m │ │ │ ├── JLAssetsLibrary.h │ │ │ └── JLAssetsLibrary.m │ │ └── JLViews │ │ │ ├── JLAlbumCell.h │ │ │ ├── JLAlbumCell.m │ │ │ ├── JLBadgeView.h │ │ │ ├── JLBadgeView.m │ │ │ ├── JLBadgeView.xib │ │ │ ├── JLGroupCell.h │ │ │ ├── JLGroupCell.m │ │ │ ├── JLScrollView.h │ │ │ └── JLScrollView.m │ └── JLBrowser │ │ ├── JLPhoto.h │ │ ├── JLPhoto.m │ │ ├── JLPhotoBrowser.h │ │ ├── JLPhotoBrowser.m │ │ ├── JLPieProgressView.h │ │ └── JLPieProgressView.m ├── Info.plist ├── JLAlbumViewController.h ├── JLAlbumViewController.m ├── JLAlbumViewController.xib ├── JLImageListView.h ├── JLImageListView.m ├── JLNetworkViewController.h ├── JLNetworkViewController.m ├── Lib │ └── SDWebImage │ │ ├── .svn │ │ ├── entries │ │ ├── prop-base │ │ │ ├── MKAnnotationView+WebCache.h.svn-base │ │ │ ├── MKAnnotationView+WebCache.m.svn-base │ │ │ ├── NSData+ImageContentType.h.svn-base │ │ │ ├── NSData+ImageContentType.m.svn-base │ │ │ ├── SDImageCache.h.svn-base │ │ │ ├── SDImageCache.m.svn-base │ │ │ ├── SDWebImageCompat.h.svn-base │ │ │ ├── SDWebImageCompat.m.svn-base │ │ │ ├── SDWebImageDecoder.h.svn-base │ │ │ ├── SDWebImageDecoder.m.svn-base │ │ │ ├── SDWebImageDownloader.h.svn-base │ │ │ ├── SDWebImageDownloader.m.svn-base │ │ │ ├── SDWebImageDownloaderOperation.h.svn-base │ │ │ ├── SDWebImageDownloaderOperation.m.svn-base │ │ │ ├── SDWebImageManager.h.svn-base │ │ │ ├── SDWebImageManager.m.svn-base │ │ │ ├── SDWebImageOperation.h.svn-base │ │ │ ├── SDWebImagePrefetcher.h.svn-base │ │ │ ├── SDWebImagePrefetcher.m.svn-base │ │ │ ├── UIButton+WebCache.h.svn-base │ │ │ ├── UIButton+WebCache.m.svn-base │ │ │ ├── UIImage+GIF.h.svn-base │ │ │ ├── UIImage+GIF.m.svn-base │ │ │ ├── UIImage+MultiFormat.h.svn-base │ │ │ ├── UIImage+MultiFormat.m.svn-base │ │ │ ├── UIImage+WebP.h.svn-base │ │ │ ├── UIImage+WebP.m.svn-base │ │ │ ├── UIImageView+HighlightedWebCache.h.svn-base │ │ │ ├── UIImageView+HighlightedWebCache.m.svn-base │ │ │ ├── UIImageView+WebCache.h.svn-base │ │ │ ├── UIImageView+WebCache.m.svn-base │ │ │ ├── UIView+WebCacheOperation.h.svn-base │ │ │ └── UIView+WebCacheOperation.m.svn-base │ │ └── text-base │ │ │ ├── MKAnnotationView+WebCache.h.svn-base │ │ │ ├── MKAnnotationView+WebCache.m.svn-base │ │ │ ├── NSData+ImageContentType.h.svn-base │ │ │ ├── NSData+ImageContentType.m.svn-base │ │ │ ├── SDImageCache.h.svn-base │ │ │ ├── SDImageCache.m.svn-base │ │ │ ├── SDWebImageCompat.h.svn-base │ │ │ ├── SDWebImageCompat.m.svn-base │ │ │ ├── SDWebImageDecoder.h.svn-base │ │ │ ├── SDWebImageDecoder.m.svn-base │ │ │ ├── SDWebImageDownloader.h.svn-base │ │ │ ├── SDWebImageDownloader.m.svn-base │ │ │ ├── SDWebImageDownloaderOperation.h.svn-base │ │ │ ├── SDWebImageDownloaderOperation.m.svn-base │ │ │ ├── SDWebImageManager.h.svn-base │ │ │ ├── SDWebImageManager.m.svn-base │ │ │ ├── SDWebImageOperation.h.svn-base │ │ │ ├── SDWebImagePrefetcher.h.svn-base │ │ │ ├── SDWebImagePrefetcher.m.svn-base │ │ │ ├── UIButton+WebCache.h.svn-base │ │ │ ├── UIButton+WebCache.m.svn-base │ │ │ ├── UIImage+GIF.h.svn-base │ │ │ ├── UIImage+GIF.m.svn-base │ │ │ ├── UIImage+MultiFormat.h.svn-base │ │ │ ├── UIImage+MultiFormat.m.svn-base │ │ │ ├── UIImage+WebP.h.svn-base │ │ │ ├── UIImage+WebP.m.svn-base │ │ │ ├── UIImageView+HighlightedWebCache.h.svn-base │ │ │ ├── UIImageView+HighlightedWebCache.m.svn-base │ │ │ ├── UIImageView+WebCache.h.svn-base │ │ │ ├── UIImageView+WebCache.m.svn-base │ │ │ ├── UIView+WebCacheOperation.h.svn-base │ │ │ └── UIView+WebCacheOperation.m.svn-base │ │ ├── MKAnnotationView+WebCache.h │ │ ├── MKAnnotationView+WebCache.m │ │ ├── NSData+ImageContentType.h │ │ ├── NSData+ImageContentType.m │ │ ├── SDImageCache.h │ │ ├── SDImageCache.m │ │ ├── SDWebImageCompat.h │ │ ├── SDWebImageCompat.m │ │ ├── SDWebImageDecoder.h │ │ ├── SDWebImageDecoder.m │ │ ├── SDWebImageDownloader.h │ │ ├── SDWebImageDownloader.m │ │ ├── SDWebImageDownloaderOperation.h │ │ ├── SDWebImageDownloaderOperation.m │ │ ├── SDWebImageManager.h │ │ ├── SDWebImageManager.m │ │ ├── SDWebImageOperation.h │ │ ├── SDWebImagePrefetcher.h │ │ ├── SDWebImagePrefetcher.m │ │ ├── UIButton+WebCache.h │ │ ├── UIButton+WebCache.m │ │ ├── UIImage+GIF.h │ │ ├── UIImage+GIF.m │ │ ├── UIImage+MultiFormat.h │ │ ├── UIImage+MultiFormat.m │ │ ├── UIImage+WebP.h │ │ ├── UIImage+WebP.m │ │ ├── UIImageView+HighlightedWebCache.h │ │ ├── UIImageView+HighlightedWebCache.m │ │ ├── UIImageView+WebCache.h │ │ ├── UIImageView+WebCache.m │ │ ├── UIView+WebCacheOperation.h │ │ └── UIView+WebCacheOperation.m ├── Picture.plist ├── ViewController.h ├── ViewController.m ├── imgs │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ ├── 6.jpg │ ├── 7.jpg │ ├── 8.jpg │ ├── 9.jpg │ ├── preview_image_failure.png │ └── preview_image_failure@2x.png └── main.m ├── JLPhotoBrowserTests ├── Info.plist └── JLPhotoBrowserTests.m ├── JLPhotoBrowserUITests ├── Info.plist └── JLPhotoBrowserUITests.m ├── README.md └── images └── show.gif /JLPhotoBrowser.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /JLPhotoBrowser.xcodeproj/project.xcworkspace/xcuserdata/XBS.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser.xcodeproj/project.xcworkspace/xcuserdata/XBS.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /JLPhotoBrowser.xcodeproj/project.xcworkspace/xcuserdata/liao.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser.xcodeproj/project.xcworkspace/xcuserdata/liao.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /JLPhotoBrowser.xcodeproj/project.xcworkspace/xcuserdata/zhangtianlong.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser.xcodeproj/project.xcworkspace/xcuserdata/zhangtianlong.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /JLPhotoBrowser.xcodeproj/xcuserdata/XBS.xcuserdatad/xcschemes/JLPhotoBrowser.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /JLPhotoBrowser.xcodeproj/xcuserdata/XBS.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | JLPhotoBrowser.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 0D4797821C2C2F6E0022198A 16 | 17 | primary 18 | 19 | 20 | 0D47979B1C2C2F6E0022198A 21 | 22 | primary 23 | 24 | 25 | 0D4797A61C2C2F6E0022198A 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /JLPhotoBrowser.xcodeproj/xcuserdata/liao.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser.xcodeproj/xcuserdata/liao.xcuserdatad/xcschemes/JLPhotoBrowser.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /JLPhotoBrowser.xcodeproj/xcuserdata/liao.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | JLPhotoBrowser.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 0D4797821C2C2F6E0022198A 16 | 17 | primary 18 | 19 | 20 | 0D47979B1C2C2F6E0022198A 21 | 22 | primary 23 | 24 | 25 | 0D4797A61C2C2F6E0022198A 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /JLPhotoBrowser.xcodeproj/xcuserdata/zhangtianlong.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser.xcodeproj/xcuserdata/zhangtianlong.xcuserdatad/xcschemes/Copy of JLPhotoBrowser.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 89 | 90 | 91 | 92 | 93 | 94 | 100 | 102 | 108 | 109 | 110 | 111 | 113 | 114 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /JLPhotoBrowser.xcodeproj/xcuserdata/zhangtianlong.xcuserdatad/xcschemes/JLPhotoBrowser.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 89 | 90 | 91 | 92 | 93 | 94 | 100 | 102 | 108 | 109 | 110 | 111 | 113 | 114 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /JLPhotoBrowser.xcodeproj/xcuserdata/zhangtianlong.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Copy of JLPhotoBrowser.xcscheme 8 | 9 | orderHint 10 | 1 11 | 12 | JLPhotoBrowser.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 0D4797821C2C2F6E0022198A 21 | 22 | primary 23 | 24 | 25 | 0D47979B1C2C2F6E0022198A 26 | 27 | primary 28 | 29 | 30 | 0D4797A61C2C2F6E0022198A 31 | 32 | primary 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /JLPhotoBrowser/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // JLPhotoBrowser 4 | // 5 | // Created by liao on 15/12/24. 6 | // Copyright © 2015年 BangGu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /JLPhotoBrowser/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // JLPhotoBrowser 4 | // 5 | // Created by liao on 15/12/24. 6 | // Copyright © 2015年 BangGu. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /JLPhotoBrowser/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLCommon/JLCommon.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLCommon.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/24. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #ifndef JLCommon_h 10 | #define JLCommon_h 11 | 12 | #define kMainScreenSize [UIScreen mainScreen].bounds.size 13 | #define kTintColor [UIColor colorWithRed:82.0/255.0 green:82.0/255.0 blue:82.0/255.0 alpha:1.0] 14 | #define kNavigationBarH 64 15 | #define kTooBarH 44 16 | 17 | 18 | #endif /* JLCommon_h */ 19 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLCommon/JLReturnImageDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLReturnImageDelegate.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/24. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol JLReturnImageDelegate 12 | 13 | /** 14 | 图片二进制数组 15 | */ 16 | - (void)returnImageDatas:(NSArray *)imageDatas; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLCommon/JLSelectedPhotoDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CommonProtocol.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/24. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol JLSelectedPhotoDelegate 12 | 13 | /** 14 | 检查选中的图片是否超过了9 15 | 16 | @return 是否可以继续添加图片 17 | */ 18 | - (BOOL)checkSelectedCount; 19 | 20 | /** 21 | 刷新按钮状态 22 | 23 | @param isAdd 是否是添加照片 24 | @param asset asset description 25 | @param refresh 是否需要刷新CollectionView 26 | */ 27 | - (void)refreshSelectedAssets:(BOOL)isAdd asset:(ALAsset *)asset refresh:(BOOL)refresh; 28 | 29 | /** 30 | 完成按钮点击 31 | */ 32 | - (void)completeItemClick; 33 | 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLControllers/JLALAssetGroupViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLALAssetGroupViewController.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/20. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JLALAssetGroupViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLControllers/JLALAssetGroupViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLALAssetGroupViewController.m 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/20. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import "JLALAssetGroupViewController.h" 10 | #import "JLThumbnailViewController.h" 11 | #import "JLAssetGroup.h" 12 | #import "JLAssetsLibrary.h" 13 | #import "JLGroupCell.h" 14 | #import "JLCommon.h" 15 | #import "JLNavigationController.h" 16 | 17 | @interface JLALAssetGroupViewController () 18 | 19 | @property (nonatomic,weak) UITableView *tableView; 20 | /** 21 | 相册模型数组 22 | */ 23 | @property (nonatomic,copy) NSArray *groups; 24 | @end 25 | 26 | @implementation JLALAssetGroupViewController 27 | 28 | - (void)viewDidLoad { 29 | 30 | [super viewDidLoad]; 31 | 32 | //1.0 初始化导航栏等…… 33 | [self setupSelf]; 34 | 35 | //2.0 创建tableView 36 | [self setupTableView]; 37 | 38 | //3.0 获取相册数组 39 | [self loadGroups]; 40 | 41 | } 42 | 43 | - (void)setupSelf{ 44 | 45 | self.navigationController.toolbarHidden = YES; 46 | 47 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"取消" style:UIBarButtonItemStylePlain target:self action:@selector(cancelBtnClick)]; 48 | self.title = @"照片"; 49 | 50 | } 51 | 52 | - (void)setupTableView{ 53 | 54 | UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, kMainScreenSize.width, kMainScreenSize.height) style:UITableViewStylePlain]; 55 | tableView.delegate = self; 56 | tableView.dataSource = self; 57 | tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 58 | [self.view addSubview:tableView]; 59 | self.tableView = tableView; 60 | 61 | } 62 | 63 | - (void)loadGroups{ 64 | 65 | [[JLAssetsLibrary shareAssetsLibrary] jl_enumeratePhotoGroups:^(NSArray *groups) { 66 | 67 | self.groups = groups; 68 | [self.tableView reloadData]; 69 | 70 | } failure:^(NSError *error) { 71 | 72 | [self cancelBtnClick]; 73 | 74 | }]; 75 | 76 | } 77 | 78 | - (void)cancelBtnClick{ 79 | 80 | [self dismissViewControllerAnimated:YES completion:NULL]; 81 | 82 | } 83 | 84 | #pragma mark - UITableViewDelegate 85 | 86 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 87 | 88 | return kCellHeight; 89 | 90 | } 91 | 92 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 93 | 94 | return self.groups.count; 95 | 96 | } 97 | 98 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 99 | 100 | JLGroupCell *cell = [JLGroupCell cellWithTableView:tableView]; 101 | cell.group = self.groups[indexPath.row]; 102 | 103 | return cell; 104 | 105 | } 106 | 107 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 108 | 109 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 110 | 111 | JLAssetGroup *group = self.groups[indexPath.row]; 112 | JLThumbnailViewController *thumbnailVc = [[JLThumbnailViewController alloc] init]; 113 | thumbnailVc.group = group.group; 114 | thumbnailVc.delegate = (JLNavigationController *)self.navigationController; 115 | [self.navigationController pushViewController:thumbnailVc animated:YES]; 116 | 117 | } 118 | 119 | 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLControllers/JLBrowserViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLBrowserViewController.h 3 | // ALAssetsLibrary 4 | // 5 | // Created by 张天龙 on 17/4/18. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "JLSelectedPhotoDelegate.h" 12 | 13 | @interface JLBrowserViewController : UIViewController 14 | 15 | /** 16 | 展示ALAsset数组 17 | 注意:预览和大图浏览都用这个,如果不用copy,预览的时候assetsArray和selectedAssets属于同一个数组,selectedAssets删除操作会影响到assetsArray数组的展示 18 | */ 19 | @property (nonatomic,copy) NSArray *assetsArray; 20 | /** 21 | 选中ALAsset数组 22 | */ 23 | @property (nonatomic,strong) NSArray *selectedAssets; 24 | /** 25 | 当前处于哪一张图片 26 | */ 27 | @property (nonatomic,assign) NSInteger currentIndex; 28 | @property (nonatomic,weak) id delegate; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLControllers/JLNavigationController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLNavigationController.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/24. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JLAssetsLibrary.h" 11 | #import "JLReturnImageDelegate.h" 12 | 13 | @interface JLNavigationController : UINavigationController 14 | 15 | @property (nonatomic,weak) id returnDelegate; 16 | 17 | + (instancetype)navigationAlbumControllerWithDelegate:(id)delegate; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLControllers/JLNavigationController.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLNavigationController.m 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/24. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import "JLNavigationController.h" 10 | #import "JLThumbnailViewController.h" 11 | #import "JLALAssetGroupViewController.h" 12 | 13 | @interface JLNavigationController () 14 | 15 | @end 16 | 17 | @implementation JLNavigationController 18 | 19 | + (instancetype)navigationAlbumControllerWithDelegate:(id)delegate{ 20 | 21 | JLALAssetGroupViewController *assetGroupVc = [[JLALAssetGroupViewController alloc] init]; 22 | JLThumbnailViewController *thumbnailVc = [[JLThumbnailViewController alloc] init]; 23 | JLNavigationController *nav = [[JLNavigationController alloc] initWithRootViewController:assetGroupVc]; 24 | thumbnailVc.delegate = nav; 25 | nav.returnDelegate = delegate; 26 | [nav pushViewController:thumbnailVc animated:NO]; 27 | 28 | return nav; 29 | 30 | } 31 | 32 | - (void)returnImageDatas:(NSArray *)imageDatas{ 33 | 34 | if (self.returnDelegate && [self.returnDelegate respondsToSelector:@selector(returnImageDatas:)]) { 35 | [self.returnDelegate returnImageDatas:imageDatas]; 36 | } 37 | 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLControllers/JLThumbnailViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLThumbnailViewController.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/20. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JLAssetsLibrary.h" 11 | #import "JLAssetGroup.h" 12 | #import "JLReturnImageDelegate.h" 13 | 14 | @interface JLThumbnailViewController : UIViewController 15 | @property (nonatomic,strong) ALAssetsGroup *group; 16 | @property (nonatomic,weak) id delegate; 17 | @end 18 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLCotegory/ALAsset+Associate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ALAsset+Associate.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/21. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ALAsset (Associate) 12 | 13 | /** 14 | 是否选中 15 | */ 16 | @property (nonatomic,assign) BOOL selected; 17 | 18 | /** 19 | 获取ALAsset的二进制数据 20 | */ 21 | - (NSData *)imageData; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLCotegory/ALAsset+Associate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ALAsset+Associate.m 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/21. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import "ALAsset+Associate.h" 10 | #import 11 | 12 | @implementation ALAsset (Associate) 13 | 14 | static char selectedKey; 15 | 16 | - (void)setSelected:(BOOL)selected{ 17 | 18 | objc_setAssociatedObject(self, &selectedKey, [NSNumber numberWithBool:selected], OBJC_ASSOCIATION_RETAIN_NONATOMIC); 19 | 20 | } 21 | 22 | - (BOOL)selected{ 23 | 24 | return [objc_getAssociatedObject(self, &selectedKey) boolValue]; 25 | 26 | } 27 | 28 | - (NSData *)imageData{ 29 | 30 | ALAssetRepresentation *assetRep = [self defaultRepresentation]; 31 | long long size = [assetRep size]; 32 | uint8_t *buff = malloc(size); 33 | 34 | NSError *err = nil; 35 | NSUInteger gotByteCount = [assetRep getBytes:buff fromOffset:0 length:size error:&err]; 36 | 37 | if (gotByteCount) { 38 | if (err) { 39 | free(buff); 40 | return nil; 41 | } 42 | } 43 | 44 | return [NSData dataWithBytesNoCopy:buff length:size freeWhenDone:YES]; 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLCotegory/UIImage+Extend.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Extend.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/22. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (Extend) 12 | 13 | /** 14 | 通过颜色获取一张图片 15 | */ 16 | + (UIImage *)imageWithColor:(UIColor *)color; 17 | 18 | /** 19 | 修正图片方向 20 | */ 21 | + (UIImage *)fixOrientation:(UIImage *)aImage ; 22 | - (UIImage *)rotateImageToOrientationUp; 23 | - (UIImage *)rotate90CounterClockwise; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLCotegory/UIView+Animation.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Animation.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/21. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (Animation) 12 | 13 | /** 14 | 点击动画 15 | */ 16 | - (void)startKeyFramesAnimation; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLCotegory/UIView+Animation.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Animation.m 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/21. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import "UIView+Animation.h" 10 | 11 | @implementation UIView (Animation) 12 | 13 | - (void)startKeyFramesAnimation{ 14 | 15 | [UIView animateKeyframesWithDuration:0.4 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^{ 16 | 17 | /* 18 | * relativeDuration:动画持续时间比例 19 | * RelativeStartTime:动画开始时间 20 | */ 21 | [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:1/4.0 animations:^{ 22 | 23 | self.transform = CGAffineTransformScale(self.transform, 1.3, 1.3); 24 | 25 | }]; 26 | 27 | [UIView addKeyframeWithRelativeStartTime:1/4.0 relativeDuration:2/4.0 animations:^{ 28 | 29 | self.transform = CGAffineTransformScale(self.transform, 0.7, 0.7); 30 | 31 | }]; 32 | 33 | [UIView addKeyframeWithRelativeStartTime:3/4.0 relativeDuration:1/4.0 animations:^{ 34 | 35 | self.transform = CGAffineTransformIdentity; 36 | 37 | }]; 38 | 39 | } completion:^(BOOL finished) { 40 | 41 | }]; 42 | 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLImages/camera_image_capture_badge@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/Classes/JLAlbum/JLImages/camera_image_capture_badge@2x.png -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLImages/camera_image_capture_badge@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/Classes/JLAlbum/JLImages/camera_image_capture_badge@3x.png -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLImages/compose_guide_check_box_default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/Classes/JLAlbum/JLImages/compose_guide_check_box_default@2x.png -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLImages/compose_guide_check_box_default@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/Classes/JLAlbum/JLImages/compose_guide_check_box_default@3x.png -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLImages/compose_guide_check_box_right@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/Classes/JLAlbum/JLImages/compose_guide_check_box_right@2x.png -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLImages/compose_guide_check_box_right@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/Classes/JLAlbum/JLImages/compose_guide_check_box_right@3x.png -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLImages/navigationbar_back_dark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/Classes/JLAlbum/JLImages/navigationbar_back_dark@2x.png -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLImages/navigationbar_back_dark@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/Classes/JLAlbum/JLImages/navigationbar_back_dark@3x.png -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLImages/navigationbar_back_withtext@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/Classes/JLAlbum/JLImages/navigationbar_back_withtext@2x.png -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLImages/navigationbar_back_withtext@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/Classes/JLAlbum/JLImages/navigationbar_back_withtext@3x.png -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLModels/JLAssetGroup.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLAssetGroup.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/20. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface JLAssetGroup : NSObject 13 | /** 14 | * 组名 15 | */ 16 | @property (nonatomic,copy) NSString *groupName; 17 | /** 18 | * 封面图 19 | */ 20 | @property (nonatomic,strong) UIImage *posterImage;; 21 | /** 22 | * 组里面的图片个数 23 | */ 24 | @property (nonatomic , assign) NSInteger assetsCount; 25 | /** 26 | * 类型 27 | */ 28 | @property (nonatomic,copy) NSString *type; 29 | /** 30 | * 组 31 | */ 32 | @property (nonatomic , strong) ALAssetsGroup *group; 33 | @end 34 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLModels/JLAssetGroup.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLAssetGroup.m 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/20. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import "JLAssetGroup.h" 10 | 11 | @implementation JLAssetGroup 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLModels/JLAssetsLibrary.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLAssetsLibrary.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/20. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | static NSString *const kCameraRoll = @"Camera Roll"; 13 | static NSString *const kGroupPropertyName = @"ALAssetsGroupPropertyName"; 14 | 15 | typedef void(^CheckCallBack)(BOOL isAuthorized); 16 | 17 | @interface JLAssetsLibrary : ALAssetsLibrary 18 | 19 | + (instancetype)shareAssetsLibrary; 20 | 21 | 22 | /** 23 | 获取所有的图片ALAssetsGroup 24 | 25 | @param callBack 成功回调 26 | @param failure 失败回调 27 | */ 28 | - (void)jl_enumeratePhotoGroups:(void (^)(NSArray *groups))callBack failure:(void (^)(NSError *error))failure; 29 | 30 | /** 31 | 通过名字为“Camera Roll”的ALAssetsGroup 32 | 33 | @param callBack callBack description 34 | @param failure 失败回调 35 | */ 36 | - (void)jl_getCameraRollGroup:(void (^)(ALAssetsGroup *group))callBack failure:(void (^)(NSError *error))failure; 37 | 38 | /** 39 | 通过ALAssetsGroup获取ALAssets 40 | 41 | @param group group description 42 | @param callBack callBack description 43 | */ 44 | - (void)jl_enumerateAssetsWithGroup:(ALAssetsGroup *)group callBack:(void (^)(NSArray *assets))callBack; 45 | 46 | /** 47 | 检查相册授权 48 | 49 | @param checkCallBack checkCallBack description 50 | */ 51 | - (void)checkAuthorizationStatus:(CheckCallBack)checkCallBack; 52 | 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLViews/JLAlbumCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlbumCell.h 3 | // ALAssetsLibrary 4 | // 5 | // Created by 张天龙 on 17/4/18. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "JLSelectedPhotoDelegate.h" 12 | 13 | @interface JLAlbumCell : UICollectionViewCell 14 | 15 | @property (nonatomic,strong) ALAsset *asset; 16 | @property (nonatomic,weak) id delegate; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLViews/JLAlbumCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlbumCell.m 3 | // ALAssetsLibrary 4 | // 5 | // Created by 张天龙 on 17/4/18. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import "JLAlbumCell.h" 10 | #import "UIView+Animation.h" 11 | #import "ALAsset+Associate.h" 12 | 13 | @interface JLAlbumCell () 14 | /** 15 | 缩略图 16 | */ 17 | @property (nonatomic,weak) UIImageView *thumbnailView; 18 | /** 19 | 选择按钮 20 | */ 21 | @property (nonatomic,weak) UIButton *selectedBtn; 22 | 23 | @end 24 | 25 | @implementation JLAlbumCell 26 | 27 | - (instancetype)initWithFrame:(CGRect)frame 28 | { 29 | self = [super initWithFrame:frame]; 30 | if (self) { 31 | 32 | UIImageView *thumbnailView = [[UIImageView alloc]init]; 33 | [self.contentView addSubview:thumbnailView]; 34 | self.thumbnailView = thumbnailView; 35 | 36 | UIButton *selectedBtn = [[UIButton alloc] init]; 37 | [selectedBtn setImage:[UIImage imageNamed:@"compose_guide_check_box_default"] forState:UIControlStateNormal]; 38 | [selectedBtn setImage:[UIImage imageNamed:@"compose_guide_check_box_right"] forState:UIControlStateSelected]; 39 | [self.contentView addSubview:selectedBtn]; 40 | [selectedBtn addTarget:self action:@selector(selectedBtnClick:) forControlEvents:UIControlEventTouchUpInside]; 41 | self.selectedBtn = selectedBtn; 42 | 43 | 44 | 45 | } 46 | return self; 47 | } 48 | 49 | 50 | - (void)selectedBtnClick:(UIButton *)btn{ 51 | 52 | //btn.selected==NO的情况下说明是要添加选中图片,要检查 53 | if (self.delegate && !btn.selected && [self.delegate respondsToSelector:@selector(checkSelectedCount)]) { 54 | 55 | if (![self.delegate checkSelectedCount]) return; 56 | 57 | } 58 | 59 | btn.selected = !btn.selected; 60 | self.asset.selected = btn.selected; 61 | 62 | if (btn.selected) [btn startKeyFramesAnimation]; 63 | 64 | if (self.delegate && [self.delegate respondsToSelector:@selector(refreshSelectedAssets:asset:refresh:)]) { 65 | [self.delegate refreshSelectedAssets:btn.selected asset:self.asset refresh:NO]; 66 | } 67 | 68 | 69 | } 70 | 71 | - (void)setAsset:(ALAsset *)asset{ 72 | 73 | if (_asset!=asset) { 74 | _asset = asset; 75 | self.thumbnailView.image = [UIImage imageWithCGImage:asset.thumbnail]; 76 | self.selectedBtn.selected = asset.selected; 77 | 78 | } 79 | 80 | } 81 | 82 | 83 | -(void)layoutSubviews{ 84 | 85 | [super layoutSubviews]; 86 | 87 | self.thumbnailView.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); 88 | CGFloat selectedHW = 32; 89 | self.selectedBtn.frame = CGRectMake(self.frame.size.width-selectedHW, 0,selectedHW , selectedHW); 90 | 91 | } 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLViews/JLBadgeView.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLBadgeView.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/21. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JLBadgeView : UIView 12 | 13 | /** 14 | 选中了多少张图片 15 | */ 16 | @property (nonatomic,assign) NSInteger badge; 17 | 18 | /** 19 | 设置选中数字 20 | 21 | @param badge 选中多少张 22 | @param animated 是否需要动画 23 | */ 24 | - (void)setBadge:(NSInteger)badge animated:(BOOL)animated; 25 | 26 | + (instancetype)badgeView; 27 | @end 28 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLViews/JLBadgeView.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLBadgeView.m 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/21. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import "JLBadgeView.h" 10 | #import "UIView+Animation.h" 11 | 12 | @interface JLBadgeView () 13 | 14 | @property (weak, nonatomic) IBOutlet UIImageView *imageView; 15 | @property (weak, nonatomic) IBOutlet UILabel *label; 16 | 17 | @end 18 | 19 | @implementation JLBadgeView 20 | 21 | +(instancetype)badgeView{ 22 | 23 | JLBadgeView *badgeView = [[[NSBundle mainBundle] loadNibNamed:@"JLBadgeView" owner:nil options:nil] lastObject]; 24 | return badgeView; 25 | 26 | } 27 | 28 | - (void)awakeFromNib{ 29 | 30 | [super awakeFromNib]; 31 | 32 | self.backgroundColor = [UIColor clearColor]; 33 | self.hidden = YES; 34 | self.imageView.image = [UIImage imageNamed:@"camera_image_capture_badge"]; 35 | 36 | } 37 | 38 | - (void)setBadge:(NSInteger)badge{ 39 | 40 | _badge = badge; 41 | 42 | self.hidden = !_badge; 43 | 44 | self.label.text = [NSString stringWithFormat:@"%ld",_badge]; 45 | 46 | } 47 | 48 | - (void)setBadge:(NSInteger)badge animated:(BOOL)animated{ 49 | 50 | self.badge = badge; 51 | 52 | if (animated) { 53 | [self.imageView startKeyFramesAnimation]; 54 | } 55 | 56 | } 57 | 58 | 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLViews/JLBadgeView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLViews/JLGroupCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLGroupCell.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/21. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "JLAssetGroup.h" 11 | 12 | #define kCellHeight 64 13 | 14 | @interface JLGroupCell : UITableViewCell 15 | 16 | @property (nonatomic,strong) JLAssetGroup *group; 17 | 18 | + (instancetype)cellWithTableView:(UITableView *)tableView; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLViews/JLGroupCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLGroupCell.m 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/21. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import "JLGroupCell.h" 10 | #import "JLCommon.h" 11 | #define kLineHeight 0.5 12 | 13 | @implementation JLGroupCell 14 | 15 | +(instancetype)cellWithTableView:(UITableView *)tableView{ 16 | 17 | static NSString *reuseIdentifier = @"groupcell"; 18 | 19 | JLGroupCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; 20 | 21 | if (!cell) { 22 | 23 | cell = [[JLGroupCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]; 24 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 25 | 26 | //底部黑线 27 | CALayer *line = [CALayer layer]; 28 | line.backgroundColor = [UIColor colorWithRed:199.0/255.0 green:199.0/255.0 blue:204.0/255.0 alpha:1.0].CGColor; 29 | line.position = CGPointMake(90, kCellHeight-kLineHeight); 30 | line.anchorPoint = CGPointMake(0, 0); 31 | line.bounds = CGRectMake(0, 0, kMainScreenSize.width-line.position.x, 0.5); 32 | [cell.layer addSublayer:line]; 33 | 34 | } 35 | 36 | return cell; 37 | 38 | } 39 | 40 | - (void)setGroup:(JLAssetGroup *)group{ 41 | 42 | _group = group; 43 | 44 | self.imageView.image = group.posterImage; 45 | 46 | NSString *description = [NSString stringWithFormat:@"%@ (%ld)",group.groupName,group.assetsCount]; 47 | 48 | NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:description attributes:@{NSForegroundColorAttributeName:[UIColor grayColor]}]; 49 | 50 | [attStr setAttributes:@{NSForegroundColorAttributeName:[UIColor blackColor],NSFontAttributeName:[UIFont boldSystemFontOfSize:17.0]} range:NSMakeRange(0, group.groupName.length)]; 51 | self.textLabel.attributedText = attStr; 52 | 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLViews/JLScrollView.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLScrollView.h 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/22. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JLScrollView : UIScrollView 12 | 13 | /** 14 | 设置图片数据 15 | */ 16 | @property (nonatomic,strong) UIImage *image; 17 | /** 18 | 获取需要放大的控件 19 | */ 20 | - (UIView *)getZoomView; 21 | 22 | @end 23 | 24 | @interface JLScrollViewDelegate : NSObject 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLAlbum/JLViews/JLScrollView.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLScrollView.m 3 | // JLPhotoAlbum 4 | // 5 | // Created by 张天龙 on 17/4/22. 6 | // Copyright © 2017年 张天龙. All rights reserved. 7 | // 8 | 9 | #import "JLScrollView.h" 10 | #import "JLCommon.h" 11 | #define kMaxH kMainScreenSize.height-kNavigationBarH-kTooBarH 12 | 13 | @interface JLScrollView () 14 | 15 | @property (nonatomic,weak) UIImageView *imageView; 16 | 17 | @end 18 | 19 | @implementation JLScrollView 20 | 21 | - (instancetype)initWithFrame:(CGRect)frame 22 | { 23 | self = [super initWithFrame:frame]; 24 | if (self) { 25 | 26 | self.maximumZoomScale=3.0; 27 | self.minimumZoomScale=1; 28 | self.showsVerticalScrollIndicator = NO; 29 | self.showsHorizontalScrollIndicator = NO; 30 | 31 | UIImageView *imageView = [[UIImageView alloc] init]; 32 | imageView.userInteractionEnabled = YES; 33 | [self addSubview:imageView]; 34 | UITapGestureRecognizer *zonmTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(zonmTap:)]; 35 | zonmTap.numberOfTapsRequired = 2; 36 | [imageView addGestureRecognizer:zonmTap]; 37 | self.imageView = imageView; 38 | 39 | 40 | 41 | } 42 | return self; 43 | } 44 | 45 | 46 | /** 47 | 点击两次放大图片 48 | */ 49 | -(void)zonmTap:(UITapGestureRecognizer *)zonmTap{ 50 | 51 | [UIView animateWithDuration:0.3 animations:^{ 52 | 53 | if (self.zoomScale==1.0) { 54 | self.zoomScale = 3.0; 55 | }else{ 56 | self.zoomScale = 1.0; 57 | } 58 | 59 | }]; 60 | 61 | } 62 | 63 | - (UIView *)getZoomView{ 64 | 65 | return self.imageView; 66 | 67 | } 68 | 69 | - (void)setImage:(UIImage *)image{ 70 | 71 | self.imageView.image = image; 72 | 73 | CGFloat radio = image.size.height/image.size.width; 74 | CGFloat imageH = kMainScreenSize.width*radio; 75 | 76 | if (imageH0) { 117 | 118 | photoF.origin.y = photoY; 119 | 120 | }else{ 121 | 122 | photoF.origin.y = 0; 123 | 124 | } 125 | 126 | photo.frame = photoF; 127 | 128 | } 129 | 130 | 131 | 132 | @end 133 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLBrowser/JLPhoto.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLPhoto.h 3 | // JLPhotoBrowser 4 | // 5 | // Created by liao on 15/12/24. 6 | // Copyright © 2015年 BangGu. All rights reserved. 7 | // 展示放大图片的imageView 8 | 9 | #import 10 | 11 | @interface JLPhoto : UIImageView 12 | /** 13 | * 原始imageView 14 | */ 15 | @property (nonatomic,strong) UIImageView *sourceImageView; 16 | /** 17 | * 大图URL 18 | */ 19 | @property (nonatomic,strong) NSString *bigImgUrl; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLBrowser/JLPhoto.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLPhoto.m 3 | // JLPhotoBrowser 4 | // 5 | // Created by liao on 15/12/24. 6 | // Copyright © 2015年 BangGu. All rights reserved. 7 | // 8 | 9 | #import "JLPhoto.h" 10 | 11 | @implementation JLPhoto 12 | 13 | - (instancetype)initWithFrame:(CGRect)frame 14 | { 15 | self = [super initWithFrame:frame]; 16 | if (self) { 17 | 18 | //不裁剪的话,缩放的时候会看到两边多余的部分 19 | self.clipsToBounds = YES; 20 | self.userInteractionEnabled = YES; 21 | self.contentMode = UIViewContentModeScaleAspectFill; 22 | 23 | } 24 | return self; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLBrowser/JLPhotoBrowser.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLScrollView.h 3 | // JLPhotoBrowser 4 | // 5 | // Created by liao on 15/12/24. 6 | // Copyright © 2015年 BangGu. All rights reserved. 7 | // 展示放大图片的滑动视图 8 | 9 | #import 10 | #import "JLPhoto.h" 11 | 12 | @interface JLPhotoBrowser : UIView 13 | /** 14 | * 存放图片的数组 15 | */ 16 | @property (nonatomic,strong) NSArray *photos; 17 | /** 18 | * 当前的index 19 | */ 20 | @property (nonatomic,assign) int currentIndex; 21 | /** 22 | * 显示图片浏览器 23 | */ 24 | -(void)show; 25 | /** 26 | * 返回图片浏览器 27 | */ 28 | + (instancetype)photoBrowser; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLBrowser/JLPieProgressView.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLPieProgressView.h 3 | // ProgressViewTest 4 | // 5 | // Created by 张天龙 on 17/3/28. 6 | // Copyright © 2017年 wanglei. All rights reserved. 7 | // 进度条 8 | 9 | #import 10 | 11 | @interface JLPieProgressView : UIView 12 | 13 | /** 14 | 进度值(0~1.0) 15 | */ 16 | @property (nonatomic, assign) CGFloat progressValue; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Classes/JLBrowser/JLPieProgressView.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLPieProgressView.m 3 | // ProgressViewTest 4 | // 5 | // Created by 张天龙 on 17/3/28. 6 | // Copyright © 2017年 wanglei. All rights reserved. 7 | // 8 | 9 | #import "JLPieProgressView.h" 10 | 11 | #define kInnerCircleRadius 10 12 | #define kOuterCircleRadius kInnerCircleRadius*2+2 13 | #define kStartAngle -M_PI/2 14 | #define kEndAngle(progress) kStartAngle+M_PI*2*progress 15 | #define JLColor(r,g,b,a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a] 16 | 17 | 18 | @implementation JLPieProgressView 19 | 20 | - (instancetype)initWithFrame:(CGRect)frame 21 | { 22 | self = [super initWithFrame:frame]; 23 | if (self) { 24 | self.backgroundColor = [UIColor clearColor]; 25 | } 26 | return self; 27 | } 28 | 29 | - (void)setProgressValue:(CGFloat)progressValue{ 30 | 31 | _progressValue = progressValue; 32 | 33 | if (progressValue==1.0) { 34 | self.hidden = YES; 35 | }else{ 36 | //重绘 37 | [self setNeedsDisplay]; 38 | } 39 | 40 | } 41 | 42 | - (void)drawRect:(CGRect)rect { 43 | 44 | CGContextRef ctx = UIGraphicsGetCurrentContext(); 45 | 46 | //画外圆 47 | [JLColor(255.0, 255.0, 255.0, 0.8) set]; 48 | 49 | CGContextAddArc(ctx, rect.size.width/2, rect.size.height/2,kOuterCircleRadius,0 , M_PI*2, 0); 50 | CGContextStrokePath(ctx); 51 | ; 52 | //画内圆 53 | CGContextSetLineWidth(ctx, kInnerCircleRadius*2); 54 | CGContextAddArc(ctx, rect.size.width/2, rect.size.height/2, kInnerCircleRadius,kStartAngle , kEndAngle(_progressValue), 0); 55 | CGContextStrokePath(ctx); 56 | 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSAppTransportSecurity 26 | 27 | NSAllowsArbitraryLoads 28 | 29 | 30 | NSPhotoLibraryUsageDescription 31 | App需要您的同意,才能访问相册 32 | UILaunchStoryboardName 33 | LaunchScreen 34 | UIMainStoryboardFile 35 | Main 36 | UIRequiredDeviceCapabilities 37 | 38 | armv7 39 | 40 | UISupportedInterfaceOrientations 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /JLPhotoBrowser/JLAlbumViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlbumViewController.h 3 | // JLPhotoBrowser 4 | // 5 | // Created by 张天龙 on 17/4/24. 6 | // Copyright © 2017年 BangGu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JLAlbumViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /JLPhotoBrowser/JLAlbumViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLAlbumViewController.m 3 | // JLPhotoBrowser 4 | // 5 | // Created by 张天龙 on 17/4/24. 6 | // Copyright © 2017年 BangGu. All rights reserved. 7 | // 8 | 9 | #import "JLAlbumViewController.h" 10 | #import "JLNavigationController.h" 11 | 12 | @interface JLAlbumViewController () 13 | 14 | @property (weak, nonatomic) IBOutlet UIView *showView; 15 | 16 | @end 17 | 18 | @implementation JLAlbumViewController 19 | 20 | - (IBAction)btnClick:(id)sender { 21 | 22 | //检查相册权限 23 | [[JLAssetsLibrary shareAssetsLibrary] checkAuthorizationStatus:^(BOOL isAuthorized) { 24 | 25 | if (isAuthorized) {//允许访问相册 26 | 27 | JLNavigationController *nav = [JLNavigationController navigationAlbumControllerWithDelegate:self]; 28 | [self presentViewController:nav animated:YES completion:NULL]; 29 | 30 | }else{//不允许访问 31 | 32 | UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:@"未能取得相册访问权限" message:nil delegate:nil cancelButtonTitle:@"我知道了" otherButtonTitles: nil]; 33 | [alerView show]; 34 | 35 | } 36 | 37 | }]; 38 | 39 | } 40 | 41 | #pragma mark - JLReturnImageDelegate 42 | 43 | /** 44 | 返回选中的图片数组 45 | 46 | @param imageDatas 图片数组 47 | */ 48 | - (void)returnImageDatas:(NSArray *)imageDatas{ 49 | 50 | [self showImage:imageDatas]; 51 | 52 | } 53 | 54 | - (void)showImage:(NSArray *)imageDatas{ 55 | 56 | for (UIView *subView in self.showView.subviews) [subView removeFromSuperview]; 57 | 58 | CGFloat imageHW = 80; 59 | CGFloat imageMaegin = 5; 60 | 61 | for (int i = 0; i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /JLPhotoBrowser/JLImageListView.h: -------------------------------------------------------------------------------- 1 | // 2 | // JLImageListView.h 3 | // JLPhotoBrowser 4 | // 5 | // Created by liao on 15/12/24. 6 | // Copyright © 2015年 BangGu. All rights reserved. 7 | // 九宫格 8 | 9 | #import 10 | 11 | @interface JLImageListView : UIView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /JLPhotoBrowser/JLImageListView.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLImageListView.m 3 | // JLPhotoBrowser 4 | // 5 | // Created by liao on 15/12/24. 6 | // Copyright © 2015年 BangGu. All rights reserved. 7 | // 8 | 9 | #define kStatusImageWidth 80 10 | #define kStatusImageHeight 80 11 | #define kStatusImageMargin 5 12 | 13 | #import "JLImageListView.h" 14 | #import "JLPhotoBrowser.h" 15 | 16 | @interface JLImageListView() 17 | /** 18 | * imageViews 19 | */ 20 | @property (nonatomic,strong) NSMutableArray *imageViews; 21 | /** 22 | * URL数组 23 | */ 24 | @property (nonatomic,strong) NSMutableArray *bigImgUrls; 25 | 26 | @end 27 | 28 | @implementation JLImageListView 29 | 30 | -(NSMutableArray *)imageViews{ 31 | 32 | if (_imageViews==nil) { 33 | 34 | _imageViews = [NSMutableArray array]; 35 | 36 | } 37 | 38 | return _imageViews; 39 | 40 | } 41 | 42 | -(NSMutableArray *)bigImgUrls{ 43 | 44 | if (_bigImgUrls==nil) { 45 | 46 | // 加载plist中的字典数组 47 | NSString *path = [[NSBundle mainBundle] pathForResource:@"Picture.plist" ofType:nil]; 48 | NSArray *tempUrls = [NSArray arrayWithContentsOfFile:path]; 49 | _bigImgUrls = [NSMutableArray arrayWithArray:tempUrls]; 50 | 51 | } 52 | 53 | return _bigImgUrls; 54 | 55 | } 56 | 57 | - (instancetype)initWithFrame:(CGRect)frame 58 | { 59 | self = [super initWithFrame:frame]; 60 | if (self) { 61 | 62 | //1.创建子视图 63 | [self setupImageViews]; 64 | 65 | } 66 | return self; 67 | } 68 | 69 | #pragma mark 创建子视图 70 | 71 | -(void)setupImageViews{ 72 | 73 | for (int i = 0; i<9; i++) { 74 | 75 | //1.创建imageView 76 | UIImageView *child = [[UIImageView alloc] init]; 77 | child.userInteractionEnabled = YES; 78 | child.image = [UIImage imageNamed:[NSString stringWithFormat:@"%d.jpg",i+1]]; 79 | child.clipsToBounds = YES; 80 | child.contentMode = UIViewContentModeScaleAspectFill; 81 | child.tag = i; 82 | 83 | //2.添加手势 84 | UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageTap:)]; 85 | [child addGestureRecognizer:tap]; 86 | 87 | //3.设置frame 88 | // 3.1 列数 89 | int column = i%3; 90 | // 3.2 行数 91 | int row = i/3; 92 | // 3.3 很据列数和行数算出x、y 93 | int childX = column * (kStatusImageWidth + kStatusImageMargin); 94 | int childY = row * (kStatusImageHeight + kStatusImageMargin); 95 | child.frame = CGRectMake(childX, childY, kStatusImageWidth, kStatusImageHeight); 96 | 97 | [self addSubview:child]; 98 | 99 | [self.imageViews addObject:child]; 100 | 101 | } 102 | 103 | } 104 | 105 | #pragma mark 图片点击 106 | 107 | -(void)imageTap:(UITapGestureRecognizer *)tap{ 108 | 109 | //1.创建JLPhoto数组 110 | NSMutableArray *photos = [NSMutableArray array]; 111 | 112 | for (int i=0; i 10 | 11 | @interface JLNetworkViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /JLPhotoBrowser/JLNetworkViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLNetworkViewController.m 3 | // JLPhotoBrowser 4 | // 5 | // Created by 张天龙 on 17/4/24. 6 | // Copyright © 2017年 BangGu. All rights reserved. 7 | // 8 | 9 | #import "JLNetworkViewController.h" 10 | #import "JLImageListView.h" 11 | //屏幕宽 12 | #define kScreenWidth [UIScreen mainScreen].bounds.size.width 13 | #define kScreenHeight [UIScreen mainScreen].bounds.size.height 14 | 15 | @interface JLNetworkViewController () 16 | 17 | @end 18 | 19 | @implementation JLNetworkViewController 20 | 21 | - (void)viewDidLoad { 22 | [super viewDidLoad]; 23 | 24 | self.view.backgroundColor = [UIColor whiteColor]; 25 | 26 | JLImageListView *imageListView = [[JLImageListView alloc] initWithFrame:CGRectMake((kScreenWidth-250)/2, 64+50, 250, kScreenHeight)]; 27 | [self.view addSubview:imageListView]; 28 | } 29 | 30 | 31 | 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/MKAnnotationView+WebCache.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/MKAnnotationView+WebCache.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/NSData+ImageContentType.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/NSData+ImageContentType.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDImageCache.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDImageCache.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImageCompat.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImageCompat.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImageDecoder.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImageDecoder.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImageDownloader.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImageDownloader.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImageDownloaderOperation.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImageDownloaderOperation.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImageManager.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImageManager.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImageOperation.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImagePrefetcher.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/SDWebImagePrefetcher.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIButton+WebCache.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIButton+WebCache.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIImage+GIF.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIImage+GIF.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIImage+MultiFormat.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIImage+MultiFormat.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIImage+WebP.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIImage+WebP.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIImageView+HighlightedWebCache.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIImageView+HighlightedWebCache.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIImageView+WebCache.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIImageView+WebCache.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIView+WebCacheOperation.h.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/prop-base/UIView+WebCacheOperation.m.svn-base: -------------------------------------------------------------------------------- 1 | K 14 2 | svn:executable 3 | V 0 4 | 5 | END 6 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/MKAnnotationView+WebCache.m.svn-base: -------------------------------------------------------------------------------- 1 | // 2 | // MKAnnotationView+WebCache.m 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 14/03/12. 6 | // Copyright (c) 2012 Dailymotion. All rights reserved. 7 | // 8 | 9 | #import "MKAnnotationView+WebCache.h" 10 | #import "objc/runtime.h" 11 | #import "UIView+WebCacheOperation.h" 12 | 13 | static char imageURLKey; 14 | 15 | @implementation MKAnnotationView (WebCache) 16 | 17 | - (NSURL *)sd_imageURL { 18 | return objc_getAssociatedObject(self, &imageURLKey); 19 | } 20 | 21 | - (void)sd_setImageWithURL:(NSURL *)url { 22 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil]; 23 | } 24 | 25 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { 26 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil]; 27 | } 28 | 29 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { 30 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil]; 31 | } 32 | 33 | - (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock { 34 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:completedBlock]; 35 | } 36 | 37 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { 38 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:completedBlock]; 39 | } 40 | 41 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { 42 | [self sd_cancelCurrentImageLoad]; 43 | 44 | objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 45 | self.image = placeholder; 46 | 47 | if (url) { 48 | __weak __typeof(self)wself = self; 49 | id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { 50 | if (!wself) return; 51 | dispatch_main_sync_safe(^{ 52 | __strong MKAnnotationView *sself = wself; 53 | if (!sself) return; 54 | if (image) { 55 | sself.image = image; 56 | } 57 | if (completedBlock && finished) { 58 | completedBlock(image, error, cacheType, url); 59 | } 60 | }); 61 | }]; 62 | [self sd_setImageLoadOperation:operation forKey:@"MKAnnotationViewImage"]; 63 | } else { 64 | dispatch_main_async_safe(^{ 65 | NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; 66 | if (completedBlock) { 67 | completedBlock(nil, error, SDImageCacheTypeNone, url); 68 | } 69 | }); 70 | } 71 | } 72 | 73 | - (void)sd_cancelCurrentImageLoad { 74 | [self sd_cancelImageLoadOperationWithKey:@"MKAnnotationViewImage"]; 75 | } 76 | 77 | @end 78 | 79 | 80 | @implementation MKAnnotationView (WebCacheDeprecated) 81 | 82 | - (NSURL *)imageURL { 83 | return [self sd_imageURL]; 84 | } 85 | 86 | - (void)setImageWithURL:(NSURL *)url { 87 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil]; 88 | } 89 | 90 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { 91 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil]; 92 | } 93 | 94 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { 95 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil]; 96 | } 97 | 98 | - (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock { 99 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 100 | if (completedBlock) { 101 | completedBlock(image, error, cacheType); 102 | } 103 | }]; 104 | } 105 | 106 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { 107 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 108 | if (completedBlock) { 109 | completedBlock(image, error, cacheType); 110 | } 111 | }]; 112 | } 113 | 114 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { 115 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 116 | if (completedBlock) { 117 | completedBlock(image, error, cacheType); 118 | } 119 | }]; 120 | } 121 | 122 | - (void)cancelCurrentImageLoad { 123 | [self sd_cancelCurrentImageLoad]; 124 | } 125 | 126 | @end 127 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/NSData+ImageContentType.h.svn-base: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Fabrice Aneche on 06/01/14. 3 | // Copyright (c) 2014 Dailymotion. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @interface NSData (ImageContentType) 9 | 10 | /** 11 | * Compute the content type for an image data 12 | * 13 | * @param data the input data 14 | * 15 | * @return the content type as string (i.e. image/jpeg, image/gif) 16 | */ 17 | + (NSString *)sd_contentTypeForImageData:(NSData *)data; 18 | 19 | @end 20 | 21 | 22 | @interface NSData (ImageContentTypeDeprecated) 23 | 24 | + (NSString *)contentTypeForImageData:(NSData *)data __deprecated_msg("Use `sd_contentTypeForImageData:`"); 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/NSData+ImageContentType.m.svn-base: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Fabrice Aneche on 06/01/14. 3 | // Copyright (c) 2014 Dailymotion. All rights reserved. 4 | // 5 | 6 | #import "NSData+ImageContentType.h" 7 | 8 | 9 | @implementation NSData (ImageContentType) 10 | 11 | + (NSString *)sd_contentTypeForImageData:(NSData *)data { 12 | uint8_t c; 13 | [data getBytes:&c length:1]; 14 | switch (c) { 15 | case 0xFF: 16 | return @"image/jpeg"; 17 | case 0x89: 18 | return @"image/png"; 19 | case 0x47: 20 | return @"image/gif"; 21 | case 0x49: 22 | case 0x4D: 23 | return @"image/tiff"; 24 | case 0x52: 25 | // R as RIFF for WEBP 26 | if ([data length] < 12) { 27 | return nil; 28 | } 29 | 30 | NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding]; 31 | if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) { 32 | return @"image/webp"; 33 | } 34 | 35 | return nil; 36 | } 37 | return nil; 38 | } 39 | 40 | @end 41 | 42 | 43 | @implementation NSData (ImageContentTypeDeprecated) 44 | 45 | + (NSString *)contentTypeForImageData:(NSData *)data { 46 | return [self sd_contentTypeForImageData:data]; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/SDWebImageCompat.h.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * (c) Jamie Pinkham 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | #import 11 | 12 | #ifdef __OBJC_GC__ 13 | #error SDWebImage does not support Objective-C Garbage Collection 14 | #endif 15 | 16 | #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 17 | #error SDWebImage doesn't support Deployement Target version < 5.0 18 | #endif 19 | 20 | #if !TARGET_OS_IPHONE 21 | #import 22 | #ifndef UIImage 23 | #define UIImage NSImage 24 | #endif 25 | #ifndef UIImageView 26 | #define UIImageView NSImageView 27 | #endif 28 | #else 29 | 30 | #import 31 | 32 | #endif 33 | 34 | #ifndef NS_ENUM 35 | #define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type 36 | #endif 37 | 38 | #ifndef NS_OPTIONS 39 | #define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type 40 | #endif 41 | 42 | #if OS_OBJECT_USE_OBJC 43 | #undef SDDispatchQueueRelease 44 | #undef SDDispatchQueueSetterSementics 45 | #define SDDispatchQueueRelease(q) 46 | #define SDDispatchQueueSetterSementics strong 47 | #else 48 | #undef SDDispatchQueueRelease 49 | #undef SDDispatchQueueSetterSementics 50 | #define SDDispatchQueueRelease(q) (dispatch_release(q)) 51 | #define SDDispatchQueueSetterSementics assign 52 | #endif 53 | 54 | extern UIImage *SDScaledImageForKey(NSString *key, UIImage *image); 55 | 56 | typedef void(^SDWebImageNoParamsBlock)(); 57 | 58 | extern NSString *const SDWebImageErrorDomain; 59 | 60 | #define dispatch_main_sync_safe(block)\ 61 | if ([NSThread isMainThread]) {\ 62 | block();\ 63 | } else {\ 64 | dispatch_sync(dispatch_get_main_queue(), block);\ 65 | } 66 | 67 | #define dispatch_main_async_safe(block)\ 68 | if ([NSThread isMainThread]) {\ 69 | block();\ 70 | } else {\ 71 | dispatch_async(dispatch_get_main_queue(), block);\ 72 | } 73 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/SDWebImageCompat.m.svn-base: -------------------------------------------------------------------------------- 1 | // 2 | // SDWebImageCompat.m 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 11/12/12. 6 | // Copyright (c) 2012 Dailymotion. All rights reserved. 7 | // 8 | 9 | #import "SDWebImageCompat.h" 10 | 11 | #if !__has_feature(objc_arc) 12 | #error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag 13 | #endif 14 | 15 | inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) { 16 | if (!image) { 17 | return nil; 18 | } 19 | 20 | if ([image.images count] > 0) { 21 | NSMutableArray *scaledImages = [NSMutableArray array]; 22 | 23 | for (UIImage *tempImage in image.images) { 24 | [scaledImages addObject:SDScaledImageForKey(key, tempImage)]; 25 | } 26 | 27 | return [UIImage animatedImageWithImages:scaledImages duration:image.duration]; 28 | } 29 | else { 30 | if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { 31 | CGFloat scale = 1.0; 32 | if (key.length >= 8) { 33 | // Search @2x. or @3x. at the end of the string, before a 3 to 4 extension length (only if key len is 8 or more @2x./@3x. + 4 len ext) 34 | NSRange range = [key rangeOfString:@"@2x." options:0 range:NSMakeRange(key.length - 8, 5)]; 35 | if (range.location != NSNotFound) { 36 | scale = 2.0; 37 | } 38 | 39 | range = [key rangeOfString:@"@3x." options:0 range:NSMakeRange(key.length - 8, 5)]; 40 | if (range.location != NSNotFound) { 41 | scale = 3.0; 42 | } 43 | } 44 | 45 | UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation]; 46 | image = scaledImage; 47 | } 48 | return image; 49 | } 50 | } 51 | 52 | NSString *const SDWebImageErrorDomain = @"SDWebImageErrorDomain"; 53 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/SDWebImageDecoder.h.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * Created by james on 9/28/11. 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | #import 12 | #import "SDWebImageCompat.h" 13 | 14 | @interface UIImage (ForceDecode) 15 | 16 | + (UIImage *)decodedImageWithImage:(UIImage *)image; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/SDWebImageDecoder.m.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * Created by james on 9/28/11. 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | #import "SDWebImageDecoder.h" 12 | 13 | @implementation UIImage (ForceDecode) 14 | 15 | + (UIImage *)decodedImageWithImage:(UIImage *)image { 16 | if (image.images) { 17 | // Do not decode animated images 18 | return image; 19 | } 20 | 21 | CGImageRef imageRef = image.CGImage; 22 | CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); 23 | CGRect imageRect = (CGRect){.origin = CGPointZero, .size = imageSize}; 24 | 25 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 26 | CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 27 | 28 | int infoMask = (bitmapInfo & kCGBitmapAlphaInfoMask); 29 | BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone || 30 | infoMask == kCGImageAlphaNoneSkipFirst || 31 | infoMask == kCGImageAlphaNoneSkipLast); 32 | 33 | // CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB. 34 | // https://developer.apple.com/library/mac/#qa/qa1037/_index.html 35 | if (infoMask == kCGImageAlphaNone && CGColorSpaceGetNumberOfComponents(colorSpace) > 1) { 36 | // Unset the old alpha info. 37 | bitmapInfo &= ~kCGBitmapAlphaInfoMask; 38 | 39 | // Set noneSkipFirst. 40 | bitmapInfo |= kCGImageAlphaNoneSkipFirst; 41 | } 42 | // Some PNGs tell us they have alpha but only 3 components. Odd. 43 | else if (!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace) == 3) { 44 | // Unset the old alpha info. 45 | bitmapInfo &= ~kCGBitmapAlphaInfoMask; 46 | bitmapInfo |= kCGImageAlphaPremultipliedFirst; 47 | } 48 | 49 | // It calculates the bytes-per-row based on the bitsPerComponent and width arguments. 50 | CGContextRef context = CGBitmapContextCreate(NULL, 51 | imageSize.width, 52 | imageSize.height, 53 | CGImageGetBitsPerComponent(imageRef), 54 | 0, 55 | colorSpace, 56 | bitmapInfo); 57 | CGColorSpaceRelease(colorSpace); 58 | 59 | // If failed, return undecompressed image 60 | if (!context) return image; 61 | 62 | CGContextDrawImage(context, imageRect, imageRef); 63 | CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context); 64 | 65 | CGContextRelease(context); 66 | 67 | UIImage *decompressedImage = [UIImage imageWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation]; 68 | CGImageRelease(decompressedImageRef); 69 | return decompressedImage; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/SDWebImageDownloaderOperation.h.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 10 | #import "SDWebImageDownloader.h" 11 | #import "SDWebImageOperation.h" 12 | 13 | extern NSString *const SDWebImageDownloadStartNotification; 14 | extern NSString *const SDWebImageDownloadReceiveResponseNotification; 15 | extern NSString *const SDWebImageDownloadStopNotification; 16 | extern NSString *const SDWebImageDownloadFinishNotification; 17 | 18 | @interface SDWebImageDownloaderOperation : NSOperation 19 | 20 | /** 21 | * The request used by the operation's connection. 22 | */ 23 | @property (strong, nonatomic, readonly) NSURLRequest *request; 24 | 25 | 26 | @property (assign, nonatomic) BOOL shouldDecompressImages; 27 | 28 | /** 29 | * Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default. 30 | * 31 | * This is the value that is returned in the `NSURLConnectionDelegate` method `-connectionShouldUseCredentialStorage:`. 32 | */ 33 | @property (nonatomic, assign) BOOL shouldUseCredentialStorage; 34 | 35 | /** 36 | * The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`. 37 | * 38 | * This will be overridden by any shared credentials that exist for the username or password of the request URL, if present. 39 | */ 40 | @property (nonatomic, strong) NSURLCredential *credential; 41 | 42 | /** 43 | * The SDWebImageDownloaderOptions for the receiver. 44 | */ 45 | @property (assign, nonatomic, readonly) SDWebImageDownloaderOptions options; 46 | 47 | /** 48 | * The expected size of data. 49 | */ 50 | @property (assign, nonatomic) NSInteger expectedSize; 51 | 52 | /** 53 | * The response returned by the operation's connection. 54 | */ 55 | @property (strong, nonatomic) NSURLResponse *response; 56 | 57 | /** 58 | * Initializes a `SDWebImageDownloaderOperation` object 59 | * 60 | * @see SDWebImageDownloaderOperation 61 | * 62 | * @param request the URL request 63 | * @param options downloader options 64 | * @param progressBlock the block executed when a new chunk of data arrives. 65 | * @note the progress block is executed on a background queue 66 | * @param completedBlock the block executed when the download is done. 67 | * @note the completed block is executed on the main queue for success. If errors are found, there is a chance the block will be executed on a background queue 68 | * @param cancelBlock the block executed if the download (operation) is cancelled 69 | * 70 | * @return the initialized instance 71 | */ 72 | - (id)initWithRequest:(NSURLRequest *)request 73 | options:(SDWebImageDownloaderOptions)options 74 | progress:(SDWebImageDownloaderProgressBlock)progressBlock 75 | completed:(SDWebImageDownloaderCompletedBlock)completedBlock 76 | cancelled:(SDWebImageNoParamsBlock)cancelBlock; 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/SDWebImageOperation.h.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 10 | 11 | @protocol SDWebImageOperation 12 | 13 | - (void)cancel; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/SDWebImagePrefetcher.h.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 10 | #import "SDWebImageManager.h" 11 | 12 | @class SDWebImagePrefetcher; 13 | 14 | @protocol SDWebImagePrefetcherDelegate 15 | 16 | @optional 17 | 18 | /** 19 | * Called when an image was prefetched. 20 | * 21 | * @param imagePrefetcher The current image prefetcher 22 | * @param imageURL The image url that was prefetched 23 | * @param finishedCount The total number of images that were prefetched (successful or not) 24 | * @param totalCount The total number of images that were to be prefetched 25 | */ 26 | - (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount; 27 | 28 | /** 29 | * Called when all images are prefetched. 30 | * @param imagePrefetcher The current image prefetcher 31 | * @param totalCount The total number of images that were prefetched (whether successful or not) 32 | * @param skippedCount The total number of images that were skipped 33 | */ 34 | - (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount; 35 | 36 | @end 37 | 38 | typedef void(^SDWebImagePrefetcherProgressBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfTotalUrls); 39 | typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfSkippedUrls); 40 | 41 | /** 42 | * Prefetch some URLs in the cache for future use. Images are downloaded in low priority. 43 | */ 44 | @interface SDWebImagePrefetcher : NSObject 45 | 46 | /** 47 | * The web image manager 48 | */ 49 | @property (strong, nonatomic, readonly) SDWebImageManager *manager; 50 | 51 | /** 52 | * Maximum number of URLs to prefetch at the same time. Defaults to 3. 53 | */ 54 | @property (nonatomic, assign) NSUInteger maxConcurrentDownloads; 55 | 56 | /** 57 | * SDWebImageOptions for prefetcher. Defaults to SDWebImageLowPriority. 58 | */ 59 | @property (nonatomic, assign) SDWebImageOptions options; 60 | 61 | /** 62 | * Queue options for Prefetcher. Defaults to Main Queue. 63 | */ 64 | @property (nonatomic, assign) dispatch_queue_t prefetcherQueue; 65 | 66 | @property (weak, nonatomic) id delegate; 67 | 68 | /** 69 | * Return the global image prefetcher instance. 70 | */ 71 | + (SDWebImagePrefetcher *)sharedImagePrefetcher; 72 | 73 | /** 74 | * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, 75 | * currently one image is downloaded at a time, 76 | * and skips images for failed downloads and proceed to the next image in the list 77 | * 78 | * @param urls list of URLs to prefetch 79 | */ 80 | - (void)prefetchURLs:(NSArray *)urls; 81 | 82 | /** 83 | * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, 84 | * currently one image is downloaded at a time, 85 | * and skips images for failed downloads and proceed to the next image in the list 86 | * 87 | * @param urls list of URLs to prefetch 88 | * @param progressBlock block to be called when progress updates; 89 | * first parameter is the number of completed (successful or not) requests, 90 | * second parameter is the total number of images originally requested to be prefetched 91 | * @param completionBlock block to be called when prefetching is completed 92 | * first param is the number of completed (successful or not) requests, 93 | * second parameter is the number of skipped requests 94 | */ 95 | - (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock; 96 | 97 | /** 98 | * Remove and cancel queued list 99 | */ 100 | - (void)cancelPrefetching; 101 | 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/UIImage+GIF.h.svn-base: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+GIF.h 3 | // LBGIFImage 4 | // 5 | // Created by Laurin Brandner on 06.01.12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (GIF) 12 | 13 | + (UIImage *)sd_animatedGIFNamed:(NSString *)name; 14 | 15 | + (UIImage *)sd_animatedGIFWithData:(NSData *)data; 16 | 17 | - (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/UIImage+GIF.m.svn-base: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+GIF.m 3 | // LBGIFImage 4 | // 5 | // Created by Laurin Brandner on 06.01.12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "UIImage+GIF.h" 10 | #import 11 | 12 | @implementation UIImage (GIF) 13 | 14 | + (UIImage *)sd_animatedGIFWithData:(NSData *)data { 15 | if (!data) { 16 | return nil; 17 | } 18 | 19 | CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); 20 | 21 | size_t count = CGImageSourceGetCount(source); 22 | 23 | UIImage *animatedImage; 24 | 25 | if (count <= 1) { 26 | animatedImage = [[UIImage alloc] initWithData:data]; 27 | } 28 | else { 29 | NSMutableArray *images = [NSMutableArray array]; 30 | 31 | NSTimeInterval duration = 0.0f; 32 | 33 | for (size_t i = 0; i < count; i++) { 34 | CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL); 35 | 36 | duration += [self sd_frameDurationAtIndex:i source:source]; 37 | 38 | [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]]; 39 | 40 | CGImageRelease(image); 41 | } 42 | 43 | if (!duration) { 44 | duration = (1.0f / 10.0f) * count; 45 | } 46 | 47 | animatedImage = [UIImage animatedImageWithImages:images duration:duration]; 48 | } 49 | 50 | CFRelease(source); 51 | 52 | return animatedImage; 53 | } 54 | 55 | + (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source { 56 | float frameDuration = 0.1f; 57 | CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil); 58 | NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties; 59 | NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary]; 60 | 61 | NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime]; 62 | if (delayTimeUnclampedProp) { 63 | frameDuration = [delayTimeUnclampedProp floatValue]; 64 | } 65 | else { 66 | 67 | NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime]; 68 | if (delayTimeProp) { 69 | frameDuration = [delayTimeProp floatValue]; 70 | } 71 | } 72 | 73 | // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. 74 | // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify 75 | // a duration of <= 10 ms. See and 76 | // for more information. 77 | 78 | if (frameDuration < 0.011f) { 79 | frameDuration = 0.100f; 80 | } 81 | 82 | CFRelease(cfFrameProperties); 83 | return frameDuration; 84 | } 85 | 86 | + (UIImage *)sd_animatedGIFNamed:(NSString *)name { 87 | CGFloat scale = [UIScreen mainScreen].scale; 88 | 89 | if (scale > 1.0f) { 90 | NSString *retinaPath = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"gif"]; 91 | 92 | NSData *data = [NSData dataWithContentsOfFile:retinaPath]; 93 | 94 | if (data) { 95 | return [UIImage sd_animatedGIFWithData:data]; 96 | } 97 | 98 | NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"]; 99 | 100 | data = [NSData dataWithContentsOfFile:path]; 101 | 102 | if (data) { 103 | return [UIImage sd_animatedGIFWithData:data]; 104 | } 105 | 106 | return [UIImage imageNamed:name]; 107 | } 108 | else { 109 | NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"]; 110 | 111 | NSData *data = [NSData dataWithContentsOfFile:path]; 112 | 113 | if (data) { 114 | return [UIImage sd_animatedGIFWithData:data]; 115 | } 116 | 117 | return [UIImage imageNamed:name]; 118 | } 119 | } 120 | 121 | - (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size { 122 | if (CGSizeEqualToSize(self.size, size) || CGSizeEqualToSize(size, CGSizeZero)) { 123 | return self; 124 | } 125 | 126 | CGSize scaledSize = size; 127 | CGPoint thumbnailPoint = CGPointZero; 128 | 129 | CGFloat widthFactor = size.width / self.size.width; 130 | CGFloat heightFactor = size.height / self.size.height; 131 | CGFloat scaleFactor = (widthFactor > heightFactor) ? widthFactor : heightFactor; 132 | scaledSize.width = self.size.width * scaleFactor; 133 | scaledSize.height = self.size.height * scaleFactor; 134 | 135 | if (widthFactor > heightFactor) { 136 | thumbnailPoint.y = (size.height - scaledSize.height) * 0.5; 137 | } 138 | else if (widthFactor < heightFactor) { 139 | thumbnailPoint.x = (size.width - scaledSize.width) * 0.5; 140 | } 141 | 142 | NSMutableArray *scaledImages = [NSMutableArray array]; 143 | 144 | UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); 145 | 146 | for (UIImage *image in self.images) { 147 | [image drawInRect:CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)]; 148 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 149 | 150 | [scaledImages addObject:newImage]; 151 | } 152 | 153 | UIGraphicsEndImageContext(); 154 | 155 | return [UIImage animatedImageWithImages:scaledImages duration:self.duration]; 156 | } 157 | 158 | @end 159 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/UIImage+MultiFormat.h.svn-base: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+MultiFormat.h 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 07/06/13. 6 | // Copyright (c) 2013 Dailymotion. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (MultiFormat) 12 | 13 | + (UIImage *)sd_imageWithData:(NSData *)data; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/UIImage+MultiFormat.m.svn-base: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+MultiFormat.m 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 07/06/13. 6 | // Copyright (c) 2013 Dailymotion. All rights reserved. 7 | // 8 | 9 | #import "UIImage+MultiFormat.h" 10 | #import "UIImage+GIF.h" 11 | #import "NSData+ImageContentType.h" 12 | #import 13 | 14 | #ifdef SD_WEBP 15 | #import "UIImage+WebP.h" 16 | #endif 17 | 18 | @implementation UIImage (MultiFormat) 19 | 20 | + (UIImage *)sd_imageWithData:(NSData *)data { 21 | UIImage *image; 22 | NSString *imageContentType = [NSData sd_contentTypeForImageData:data]; 23 | if ([imageContentType isEqualToString:@"image/gif"]) { 24 | image = [UIImage sd_animatedGIFWithData:data]; 25 | } 26 | #ifdef SD_WEBP 27 | else if ([imageContentType isEqualToString:@"image/webp"]) 28 | { 29 | image = [UIImage sd_imageWithWebPData:data]; 30 | } 31 | #endif 32 | else { 33 | image = [[UIImage alloc] initWithData:data]; 34 | UIImageOrientation orientation = [self sd_imageOrientationFromImageData:data]; 35 | if (orientation != UIImageOrientationUp) { 36 | image = [UIImage imageWithCGImage:image.CGImage 37 | scale:image.scale 38 | orientation:orientation]; 39 | } 40 | } 41 | 42 | 43 | return image; 44 | } 45 | 46 | 47 | +(UIImageOrientation)sd_imageOrientationFromImageData:(NSData *)imageData { 48 | UIImageOrientation result = UIImageOrientationUp; 49 | CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL); 50 | if (imageSource) { 51 | CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL); 52 | if (properties) { 53 | CFTypeRef val; 54 | int exifOrientation; 55 | val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation); 56 | if (val) { 57 | CFNumberGetValue(val, kCFNumberIntType, &exifOrientation); 58 | result = [self sd_exifOrientationToiOSOrientation:exifOrientation]; 59 | } // else - if it's not set it remains at up 60 | CFRelease((CFTypeRef) properties); 61 | } else { 62 | //NSLog(@"NO PROPERTIES, FAIL"); 63 | } 64 | CFRelease(imageSource); 65 | } 66 | return result; 67 | } 68 | 69 | #pragma mark EXIF orientation tag converter 70 | // Convert an EXIF image orientation to an iOS one. 71 | // reference see here: http://sylvana.net/jpegcrop/exif_orientation.html 72 | + (UIImageOrientation) sd_exifOrientationToiOSOrientation:(int)exifOrientation { 73 | UIImageOrientation orientation = UIImageOrientationUp; 74 | switch (exifOrientation) { 75 | case 1: 76 | orientation = UIImageOrientationUp; 77 | break; 78 | 79 | case 3: 80 | orientation = UIImageOrientationDown; 81 | break; 82 | 83 | case 8: 84 | orientation = UIImageOrientationLeft; 85 | break; 86 | 87 | case 6: 88 | orientation = UIImageOrientationRight; 89 | break; 90 | 91 | case 2: 92 | orientation = UIImageOrientationUpMirrored; 93 | break; 94 | 95 | case 4: 96 | orientation = UIImageOrientationDownMirrored; 97 | break; 98 | 99 | case 5: 100 | orientation = UIImageOrientationLeftMirrored; 101 | break; 102 | 103 | case 7: 104 | orientation = UIImageOrientationRightMirrored; 105 | break; 106 | default: 107 | break; 108 | } 109 | return orientation; 110 | } 111 | 112 | 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/UIImage+WebP.h.svn-base: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+WebP.h 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 07/06/13. 6 | // Copyright (c) 2013 Dailymotion. All rights reserved. 7 | // 8 | 9 | #ifdef SD_WEBP 10 | 11 | #import 12 | 13 | // Fix for issue #416 Undefined symbols for architecture armv7 since WebP introduction when deploying to device 14 | void WebPInitPremultiplyNEON(void); 15 | 16 | void WebPInitUpsamplersNEON(void); 17 | 18 | void VP8DspInitNEON(void); 19 | 20 | @interface UIImage (WebP) 21 | 22 | + (UIImage *)sd_imageWithWebPData:(NSData *)data; 23 | 24 | @end 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/UIImage+WebP.m.svn-base: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+WebP.m 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 07/06/13. 6 | // Copyright (c) 2013 Dailymotion. All rights reserved. 7 | // 8 | 9 | #ifdef SD_WEBP 10 | #import "UIImage+WebP.h" 11 | #import "webp/decode.h" 12 | 13 | // Callback for CGDataProviderRelease 14 | static void FreeImageData(void *info, const void *data, size_t size) 15 | { 16 | free((void *)data); 17 | } 18 | 19 | @implementation UIImage (WebP) 20 | 21 | + (UIImage *)sd_imageWithWebPData:(NSData *)data { 22 | WebPDecoderConfig config; 23 | if (!WebPInitDecoderConfig(&config)) { 24 | return nil; 25 | } 26 | 27 | if (WebPGetFeatures(data.bytes, data.length, &config.input) != VP8_STATUS_OK) { 28 | return nil; 29 | } 30 | 31 | config.output.colorspace = config.input.has_alpha ? MODE_rgbA : MODE_RGB; 32 | config.options.use_threads = 1; 33 | 34 | // Decode the WebP image data into a RGBA value array. 35 | if (WebPDecode(data.bytes, data.length, &config) != VP8_STATUS_OK) { 36 | return nil; 37 | } 38 | 39 | int width = config.input.width; 40 | int height = config.input.height; 41 | if (config.options.use_scaling) { 42 | width = config.options.scaled_width; 43 | height = config.options.scaled_height; 44 | } 45 | 46 | // Construct a UIImage from the decoded RGBA value array. 47 | CGDataProviderRef provider = 48 | CGDataProviderCreateWithData(NULL, config.output.u.RGBA.rgba, config.output.u.RGBA.size, FreeImageData); 49 | CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); 50 | CGBitmapInfo bitmapInfo = config.input.has_alpha ? kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast : 0; 51 | size_t components = config.input.has_alpha ? 4 : 3; 52 | CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; 53 | CGImageRef imageRef = CGImageCreate(width, height, 8, components * 8, components * width, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); 54 | 55 | CGColorSpaceRelease(colorSpaceRef); 56 | CGDataProviderRelease(provider); 57 | 58 | UIImage *image = [[UIImage alloc] initWithCGImage:imageRef]; 59 | CGImageRelease(imageRef); 60 | 61 | return image; 62 | } 63 | 64 | @end 65 | 66 | #if !COCOAPODS 67 | // Functions to resolve some undefined symbols when using WebP and force_load flag 68 | void WebPInitPremultiplyNEON(void) {} 69 | void WebPInitUpsamplersNEON(void) {} 70 | void VP8DspInitNEON(void) {} 71 | #endif 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/UIImageView+HighlightedWebCache.h.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 10 | #import "SDWebImageCompat.h" 11 | #import "SDWebImageManager.h" 12 | 13 | /** 14 | * Integrates SDWebImage async downloading and caching of remote images with UIImageView for highlighted state. 15 | */ 16 | @interface UIImageView (HighlightedWebCache) 17 | 18 | /** 19 | * Set the imageView `highlightedImage` with an `url`. 20 | * 21 | * The download is asynchronous and cached. 22 | * 23 | * @param url The url for the image. 24 | */ 25 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url; 26 | 27 | /** 28 | * Set the imageView `highlightedImage` with an `url` and custom options. 29 | * 30 | * The download is asynchronous and cached. 31 | * 32 | * @param url The url for the image. 33 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 34 | */ 35 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options; 36 | 37 | /** 38 | * Set the imageView `highlightedImage` with an `url`. 39 | * 40 | * The download is asynchronous and cached. 41 | * 42 | * @param url The url for the image. 43 | * @param completedBlock A block called when operation has been completed. This block has no return value 44 | * and takes the requested UIImage as first parameter. In case of error the image parameter 45 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 46 | * indicating if the image was retrived from the local cache or from the network. 47 | * The fourth parameter is the original image url. 48 | */ 49 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; 50 | 51 | /** 52 | * Set the imageView `highlightedImage` with an `url` and custom options. 53 | * 54 | * The download is asynchronous and cached. 55 | * 56 | * @param url The url for the image. 57 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 58 | * @param completedBlock A block called when operation has been completed. This block has no return value 59 | * and takes the requested UIImage as first parameter. In case of error the image parameter 60 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 61 | * indicating if the image was retrived from the local cache or from the network. 62 | * The fourth parameter is the original image url. 63 | */ 64 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; 65 | 66 | /** 67 | * Set the imageView `highlightedImage` with an `url` and custom options. 68 | * 69 | * The download is asynchronous and cached. 70 | * 71 | * @param url The url for the image. 72 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 73 | * @param progressBlock A block called while image is downloading 74 | * @param completedBlock A block called when operation has been completed. This block has no return value 75 | * and takes the requested UIImage as first parameter. In case of error the image parameter 76 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 77 | * indicating if the image was retrived from the local cache or from the network. 78 | * The fourth parameter is the original image url. 79 | */ 80 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; 81 | 82 | /** 83 | * Cancel the current download 84 | */ 85 | - (void)sd_cancelCurrentHighlightedImageLoad; 86 | 87 | @end 88 | 89 | 90 | @interface UIImageView (HighlightedWebCacheDeprecated) 91 | 92 | - (void)setHighlightedImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:`"); 93 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:`"); 94 | - (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:completed:`"); 95 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:completed:`"); 96 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:progress:completed:`"); 97 | 98 | - (void)cancelCurrentHighlightedImageLoad __deprecated_msg("Use `sd_cancelCurrentHighlightedImageLoad`"); 99 | 100 | @end 101 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/UIImageView+HighlightedWebCache.m.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 "UIImageView+HighlightedWebCache.h" 10 | #import "UIView+WebCacheOperation.h" 11 | 12 | #define UIImageViewHighlightedWebCacheOperationKey @"highlightedImage" 13 | 14 | @implementation UIImageView (HighlightedWebCache) 15 | 16 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url { 17 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil]; 18 | } 19 | 20 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options { 21 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil]; 22 | } 23 | 24 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock { 25 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock]; 26 | } 27 | 28 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { 29 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock]; 30 | } 31 | 32 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { 33 | [self sd_cancelCurrentHighlightedImageLoad]; 34 | 35 | if (url) { 36 | __weak __typeof(self)wself = self; 37 | id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { 38 | if (!wself) return; 39 | dispatch_main_sync_safe (^ 40 | { 41 | if (!wself) return; 42 | if (image) { 43 | wself.highlightedImage = image; 44 | [wself setNeedsLayout]; 45 | } 46 | if (completedBlock && finished) { 47 | completedBlock(image, error, cacheType, url); 48 | } 49 | }); 50 | }]; 51 | [self sd_setImageLoadOperation:operation forKey:UIImageViewHighlightedWebCacheOperationKey]; 52 | } else { 53 | dispatch_main_async_safe(^{ 54 | NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; 55 | if (completedBlock) { 56 | completedBlock(nil, error, SDImageCacheTypeNone, url); 57 | } 58 | }); 59 | } 60 | } 61 | 62 | - (void)sd_cancelCurrentHighlightedImageLoad { 63 | [self sd_cancelImageLoadOperationWithKey:UIImageViewHighlightedWebCacheOperationKey]; 64 | } 65 | 66 | @end 67 | 68 | 69 | @implementation UIImageView (HighlightedWebCacheDeprecated) 70 | 71 | - (void)setHighlightedImageWithURL:(NSURL *)url { 72 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil]; 73 | } 74 | 75 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options { 76 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil]; 77 | } 78 | 79 | - (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock { 80 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 81 | if (completedBlock) { 82 | completedBlock(image, error, cacheType); 83 | } 84 | }]; 85 | } 86 | 87 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { 88 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 89 | if (completedBlock) { 90 | completedBlock(image, error, cacheType); 91 | } 92 | }]; 93 | } 94 | 95 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock { 96 | [self sd_setHighlightedImageWithURL:url options:0 progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 97 | if (completedBlock) { 98 | completedBlock(image, error, cacheType); 99 | } 100 | }]; 101 | } 102 | 103 | - (void)cancelCurrentHighlightedImageLoad { 104 | [self sd_cancelCurrentHighlightedImageLoad]; 105 | } 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/UIView+WebCacheOperation.h.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 10 | #import "SDWebImageManager.h" 11 | 12 | @interface UIView (WebCacheOperation) 13 | 14 | /** 15 | * Set the image load operation (storage in a UIView based dictionary) 16 | * 17 | * @param operation the operation 18 | * @param key key for storing the operation 19 | */ 20 | - (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key; 21 | 22 | /** 23 | * Cancel all operations for the current UIView and key 24 | * 25 | * @param key key for identifying the operations 26 | */ 27 | - (void)sd_cancelImageLoadOperationWithKey:(NSString *)key; 28 | 29 | /** 30 | * Just remove the operations corresponding to the current UIView and key without cancelling them 31 | * 32 | * @param key key for identifying the operations 33 | */ 34 | - (void)sd_removeImageLoadOperationWithKey:(NSString *)key; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/.svn/text-base/UIView+WebCacheOperation.m.svn-base: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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+WebCacheOperation.h" 10 | #import "objc/runtime.h" 11 | 12 | static char loadOperationKey; 13 | 14 | @implementation UIView (WebCacheOperation) 15 | 16 | - (NSMutableDictionary *)operationDictionary { 17 | NSMutableDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey); 18 | if (operations) { 19 | return operations; 20 | } 21 | operations = [NSMutableDictionary dictionary]; 22 | objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 23 | return operations; 24 | } 25 | 26 | - (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key { 27 | [self sd_cancelImageLoadOperationWithKey:key]; 28 | NSMutableDictionary *operationDictionary = [self operationDictionary]; 29 | [operationDictionary setObject:operation forKey:key]; 30 | } 31 | 32 | - (void)sd_cancelImageLoadOperationWithKey:(NSString *)key { 33 | // Cancel in progress downloader from queue 34 | NSMutableDictionary *operationDictionary = [self operationDictionary]; 35 | id operations = [operationDictionary objectForKey:key]; 36 | if (operations) { 37 | if ([operations isKindOfClass:[NSArray class]]) { 38 | for (id operation in operations) { 39 | if (operation) { 40 | [operation cancel]; 41 | } 42 | } 43 | } else if ([operations conformsToProtocol:@protocol(SDWebImageOperation)]){ 44 | [(id) operations cancel]; 45 | } 46 | [operationDictionary removeObjectForKey:key]; 47 | } 48 | } 49 | 50 | - (void)sd_removeImageLoadOperationWithKey:(NSString *)key { 51 | NSMutableDictionary *operationDictionary = [self operationDictionary]; 52 | [operationDictionary removeObjectForKey:key]; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/MKAnnotationView+WebCache.m: -------------------------------------------------------------------------------- 1 | // 2 | // MKAnnotationView+WebCache.m 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 14/03/12. 6 | // Copyright (c) 2012 Dailymotion. All rights reserved. 7 | // 8 | 9 | #import "MKAnnotationView+WebCache.h" 10 | #import "objc/runtime.h" 11 | #import "UIView+WebCacheOperation.h" 12 | 13 | static char imageURLKey; 14 | 15 | @implementation MKAnnotationView (WebCache) 16 | 17 | - (NSURL *)sd_imageURL { 18 | return objc_getAssociatedObject(self, &imageURLKey); 19 | } 20 | 21 | - (void)sd_setImageWithURL:(NSURL *)url { 22 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil]; 23 | } 24 | 25 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { 26 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil]; 27 | } 28 | 29 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { 30 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil]; 31 | } 32 | 33 | - (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock { 34 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:completedBlock]; 35 | } 36 | 37 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { 38 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:completedBlock]; 39 | } 40 | 41 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { 42 | [self sd_cancelCurrentImageLoad]; 43 | 44 | objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 45 | self.image = placeholder; 46 | 47 | if (url) { 48 | __weak __typeof(self)wself = self; 49 | id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { 50 | if (!wself) return; 51 | dispatch_main_sync_safe(^{ 52 | __strong MKAnnotationView *sself = wself; 53 | if (!sself) return; 54 | if (image) { 55 | sself.image = image; 56 | } 57 | if (completedBlock && finished) { 58 | completedBlock(image, error, cacheType, url); 59 | } 60 | }); 61 | }]; 62 | [self sd_setImageLoadOperation:operation forKey:@"MKAnnotationViewImage"]; 63 | } else { 64 | dispatch_main_async_safe(^{ 65 | NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; 66 | if (completedBlock) { 67 | completedBlock(nil, error, SDImageCacheTypeNone, url); 68 | } 69 | }); 70 | } 71 | } 72 | 73 | - (void)sd_cancelCurrentImageLoad { 74 | [self sd_cancelImageLoadOperationWithKey:@"MKAnnotationViewImage"]; 75 | } 76 | 77 | @end 78 | 79 | 80 | @implementation MKAnnotationView (WebCacheDeprecated) 81 | 82 | - (NSURL *)imageURL { 83 | return [self sd_imageURL]; 84 | } 85 | 86 | - (void)setImageWithURL:(NSURL *)url { 87 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil]; 88 | } 89 | 90 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { 91 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil]; 92 | } 93 | 94 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { 95 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil]; 96 | } 97 | 98 | - (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock { 99 | [self sd_setImageWithURL:url placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 100 | if (completedBlock) { 101 | completedBlock(image, error, cacheType); 102 | } 103 | }]; 104 | } 105 | 106 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { 107 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 108 | if (completedBlock) { 109 | completedBlock(image, error, cacheType); 110 | } 111 | }]; 112 | } 113 | 114 | - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { 115 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 116 | if (completedBlock) { 117 | completedBlock(image, error, cacheType); 118 | } 119 | }]; 120 | } 121 | 122 | - (void)cancelCurrentImageLoad { 123 | [self sd_cancelCurrentImageLoad]; 124 | } 125 | 126 | @end 127 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/NSData+ImageContentType.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Fabrice Aneche on 06/01/14. 3 | // Copyright (c) 2014 Dailymotion. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | @interface NSData (ImageContentType) 9 | 10 | /** 11 | * Compute the content type for an image data 12 | * 13 | * @param data the input data 14 | * 15 | * @return the content type as string (i.e. image/jpeg, image/gif) 16 | */ 17 | + (NSString *)sd_contentTypeForImageData:(NSData *)data; 18 | 19 | @end 20 | 21 | 22 | @interface NSData (ImageContentTypeDeprecated) 23 | 24 | + (NSString *)contentTypeForImageData:(NSData *)data __deprecated_msg("Use `sd_contentTypeForImageData:`"); 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/NSData+ImageContentType.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Fabrice Aneche on 06/01/14. 3 | // Copyright (c) 2014 Dailymotion. All rights reserved. 4 | // 5 | 6 | #import "NSData+ImageContentType.h" 7 | 8 | 9 | @implementation NSData (ImageContentType) 10 | 11 | + (NSString *)sd_contentTypeForImageData:(NSData *)data { 12 | uint8_t c; 13 | [data getBytes:&c length:1]; 14 | switch (c) { 15 | case 0xFF: 16 | return @"image/jpeg"; 17 | case 0x89: 18 | return @"image/png"; 19 | case 0x47: 20 | return @"image/gif"; 21 | case 0x49: 22 | case 0x4D: 23 | return @"image/tiff"; 24 | case 0x52: 25 | // R as RIFF for WEBP 26 | if ([data length] < 12) { 27 | return nil; 28 | } 29 | 30 | NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding]; 31 | if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) { 32 | return @"image/webp"; 33 | } 34 | 35 | return nil; 36 | } 37 | return nil; 38 | } 39 | 40 | @end 41 | 42 | 43 | @implementation NSData (ImageContentTypeDeprecated) 44 | 45 | + (NSString *)contentTypeForImageData:(NSData *)data { 46 | return [self sd_contentTypeForImageData:data]; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/SDWebImageCompat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * (c) Jamie Pinkham 5 | * 6 | * For the full copyright and license information, please view the LICENSE 7 | * file that was distributed with this source code. 8 | */ 9 | 10 | #import 11 | 12 | #ifdef __OBJC_GC__ 13 | #error SDWebImage does not support Objective-C Garbage Collection 14 | #endif 15 | 16 | #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 17 | #error SDWebImage doesn't support Deployement Target version < 5.0 18 | #endif 19 | 20 | #if !TARGET_OS_IPHONE 21 | #import 22 | #ifndef UIImage 23 | #define UIImage NSImage 24 | #endif 25 | #ifndef UIImageView 26 | #define UIImageView NSImageView 27 | #endif 28 | #else 29 | 30 | #import 31 | 32 | #endif 33 | 34 | #ifndef NS_ENUM 35 | #define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type 36 | #endif 37 | 38 | #ifndef NS_OPTIONS 39 | #define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type 40 | #endif 41 | 42 | #if OS_OBJECT_USE_OBJC 43 | #undef SDDispatchQueueRelease 44 | #undef SDDispatchQueueSetterSementics 45 | #define SDDispatchQueueRelease(q) 46 | #define SDDispatchQueueSetterSementics strong 47 | #else 48 | #undef SDDispatchQueueRelease 49 | #undef SDDispatchQueueSetterSementics 50 | #define SDDispatchQueueRelease(q) (dispatch_release(q)) 51 | #define SDDispatchQueueSetterSementics assign 52 | #endif 53 | 54 | extern UIImage *SDScaledImageForKey(NSString *key, UIImage *image); 55 | 56 | typedef void(^SDWebImageNoParamsBlock)(); 57 | 58 | extern NSString *const SDWebImageErrorDomain; 59 | 60 | #define dispatch_main_sync_safe(block)\ 61 | if ([NSThread isMainThread]) {\ 62 | block();\ 63 | } else {\ 64 | dispatch_sync(dispatch_get_main_queue(), block);\ 65 | } 66 | 67 | #define dispatch_main_async_safe(block)\ 68 | if ([NSThread isMainThread]) {\ 69 | block();\ 70 | } else {\ 71 | dispatch_async(dispatch_get_main_queue(), block);\ 72 | } 73 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/SDWebImageCompat.m: -------------------------------------------------------------------------------- 1 | // 2 | // SDWebImageCompat.m 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 11/12/12. 6 | // Copyright (c) 2012 Dailymotion. All rights reserved. 7 | // 8 | 9 | #import "SDWebImageCompat.h" 10 | 11 | #if !__has_feature(objc_arc) 12 | #error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag 13 | #endif 14 | 15 | inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) { 16 | if (!image) { 17 | return nil; 18 | } 19 | 20 | if ([image.images count] > 0) { 21 | NSMutableArray *scaledImages = [NSMutableArray array]; 22 | 23 | for (UIImage *tempImage in image.images) { 24 | [scaledImages addObject:SDScaledImageForKey(key, tempImage)]; 25 | } 26 | 27 | return [UIImage animatedImageWithImages:scaledImages duration:image.duration]; 28 | } 29 | else { 30 | if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { 31 | CGFloat scale = 1.0; 32 | if (key.length >= 8) { 33 | // Search @2x. or @3x. at the end of the string, before a 3 to 4 extension length (only if key len is 8 or more @2x./@3x. + 4 len ext) 34 | NSRange range = [key rangeOfString:@"@2x." options:0 range:NSMakeRange(key.length - 8, 5)]; 35 | if (range.location != NSNotFound) { 36 | scale = 2.0; 37 | } 38 | 39 | range = [key rangeOfString:@"@3x." options:0 range:NSMakeRange(key.length - 8, 5)]; 40 | if (range.location != NSNotFound) { 41 | scale = 3.0; 42 | } 43 | } 44 | 45 | UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation]; 46 | image = scaledImage; 47 | } 48 | return image; 49 | } 50 | } 51 | 52 | NSString *const SDWebImageErrorDomain = @"SDWebImageErrorDomain"; 53 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/SDWebImageDecoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * Created by james on 9/28/11. 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | #import 12 | #import "SDWebImageCompat.h" 13 | 14 | @interface UIImage (ForceDecode) 15 | 16 | + (UIImage *)decodedImageWithImage:(UIImage *)image; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/SDWebImageDecoder.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 4 | * 5 | * Created by james on 9/28/11. 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | 11 | #import "SDWebImageDecoder.h" 12 | 13 | @implementation UIImage (ForceDecode) 14 | 15 | + (UIImage *)decodedImageWithImage:(UIImage *)image { 16 | if (image.images) { 17 | // Do not decode animated images 18 | return image; 19 | } 20 | 21 | CGImageRef imageRef = image.CGImage; 22 | CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); 23 | CGRect imageRect = (CGRect){.origin = CGPointZero, .size = imageSize}; 24 | 25 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 26 | CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); 27 | 28 | int infoMask = (bitmapInfo & kCGBitmapAlphaInfoMask); 29 | BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone || 30 | infoMask == kCGImageAlphaNoneSkipFirst || 31 | infoMask == kCGImageAlphaNoneSkipLast); 32 | 33 | // CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB. 34 | // https://developer.apple.com/library/mac/#qa/qa1037/_index.html 35 | if (infoMask == kCGImageAlphaNone && CGColorSpaceGetNumberOfComponents(colorSpace) > 1) { 36 | // Unset the old alpha info. 37 | bitmapInfo &= ~kCGBitmapAlphaInfoMask; 38 | 39 | // Set noneSkipFirst. 40 | bitmapInfo |= kCGImageAlphaNoneSkipFirst; 41 | } 42 | // Some PNGs tell us they have alpha but only 3 components. Odd. 43 | else if (!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace) == 3) { 44 | // Unset the old alpha info. 45 | bitmapInfo &= ~kCGBitmapAlphaInfoMask; 46 | bitmapInfo |= kCGImageAlphaPremultipliedFirst; 47 | } 48 | 49 | // It calculates the bytes-per-row based on the bitsPerComponent and width arguments. 50 | CGContextRef context = CGBitmapContextCreate(NULL, 51 | imageSize.width, 52 | imageSize.height, 53 | CGImageGetBitsPerComponent(imageRef), 54 | 0, 55 | colorSpace, 56 | bitmapInfo); 57 | CGColorSpaceRelease(colorSpace); 58 | 59 | // If failed, return undecompressed image 60 | if (!context) return image; 61 | 62 | CGContextDrawImage(context, imageRect, imageRef); 63 | CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context); 64 | 65 | CGContextRelease(context); 66 | 67 | UIImage *decompressedImage = [UIImage imageWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation]; 68 | CGImageRelease(decompressedImageRef); 69 | return decompressedImage; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/SDWebImageDownloaderOperation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 10 | #import "SDWebImageDownloader.h" 11 | #import "SDWebImageOperation.h" 12 | 13 | extern NSString *const SDWebImageDownloadStartNotification; 14 | extern NSString *const SDWebImageDownloadReceiveResponseNotification; 15 | extern NSString *const SDWebImageDownloadStopNotification; 16 | extern NSString *const SDWebImageDownloadFinishNotification; 17 | 18 | @interface SDWebImageDownloaderOperation : NSOperation 19 | 20 | /** 21 | * The request used by the operation's connection. 22 | */ 23 | @property (strong, nonatomic, readonly) NSURLRequest *request; 24 | 25 | 26 | @property (assign, nonatomic) BOOL shouldDecompressImages; 27 | 28 | /** 29 | * Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default. 30 | * 31 | * This is the value that is returned in the `NSURLConnectionDelegate` method `-connectionShouldUseCredentialStorage:`. 32 | */ 33 | @property (nonatomic, assign) BOOL shouldUseCredentialStorage; 34 | 35 | /** 36 | * The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`. 37 | * 38 | * This will be overridden by any shared credentials that exist for the username or password of the request URL, if present. 39 | */ 40 | @property (nonatomic, strong) NSURLCredential *credential; 41 | 42 | /** 43 | * The SDWebImageDownloaderOptions for the receiver. 44 | */ 45 | @property (assign, nonatomic, readonly) SDWebImageDownloaderOptions options; 46 | 47 | /** 48 | * The expected size of data. 49 | */ 50 | @property (assign, nonatomic) NSInteger expectedSize; 51 | 52 | /** 53 | * The response returned by the operation's connection. 54 | */ 55 | @property (strong, nonatomic) NSURLResponse *response; 56 | 57 | /** 58 | * Initializes a `SDWebImageDownloaderOperation` object 59 | * 60 | * @see SDWebImageDownloaderOperation 61 | * 62 | * @param request the URL request 63 | * @param options downloader options 64 | * @param progressBlock the block executed when a new chunk of data arrives. 65 | * @note the progress block is executed on a background queue 66 | * @param completedBlock the block executed when the download is done. 67 | * @note the completed block is executed on the main queue for success. If errors are found, there is a chance the block will be executed on a background queue 68 | * @param cancelBlock the block executed if the download (operation) is cancelled 69 | * 70 | * @return the initialized instance 71 | */ 72 | - (id)initWithRequest:(NSURLRequest *)request 73 | options:(SDWebImageDownloaderOptions)options 74 | progress:(SDWebImageDownloaderProgressBlock)progressBlock 75 | completed:(SDWebImageDownloaderCompletedBlock)completedBlock 76 | cancelled:(SDWebImageNoParamsBlock)cancelBlock; 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/SDWebImageOperation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 10 | 11 | @protocol SDWebImageOperation 12 | 13 | - (void)cancel; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/SDWebImagePrefetcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 10 | #import "SDWebImageManager.h" 11 | 12 | @class SDWebImagePrefetcher; 13 | 14 | @protocol SDWebImagePrefetcherDelegate 15 | 16 | @optional 17 | 18 | /** 19 | * Called when an image was prefetched. 20 | * 21 | * @param imagePrefetcher The current image prefetcher 22 | * @param imageURL The image url that was prefetched 23 | * @param finishedCount The total number of images that were prefetched (successful or not) 24 | * @param totalCount The total number of images that were to be prefetched 25 | */ 26 | - (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount; 27 | 28 | /** 29 | * Called when all images are prefetched. 30 | * @param imagePrefetcher The current image prefetcher 31 | * @param totalCount The total number of images that were prefetched (whether successful or not) 32 | * @param skippedCount The total number of images that were skipped 33 | */ 34 | - (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount; 35 | 36 | @end 37 | 38 | typedef void(^SDWebImagePrefetcherProgressBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfTotalUrls); 39 | typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfSkippedUrls); 40 | 41 | /** 42 | * Prefetch some URLs in the cache for future use. Images are downloaded in low priority. 43 | */ 44 | @interface SDWebImagePrefetcher : NSObject 45 | 46 | /** 47 | * The web image manager 48 | */ 49 | @property (strong, nonatomic, readonly) SDWebImageManager *manager; 50 | 51 | /** 52 | * Maximum number of URLs to prefetch at the same time. Defaults to 3. 53 | */ 54 | @property (nonatomic, assign) NSUInteger maxConcurrentDownloads; 55 | 56 | /** 57 | * SDWebImageOptions for prefetcher. Defaults to SDWebImageLowPriority. 58 | */ 59 | @property (nonatomic, assign) SDWebImageOptions options; 60 | 61 | /** 62 | * Queue options for Prefetcher. Defaults to Main Queue. 63 | */ 64 | @property (nonatomic, assign) dispatch_queue_t prefetcherQueue; 65 | 66 | @property (weak, nonatomic) id delegate; 67 | 68 | /** 69 | * Return the global image prefetcher instance. 70 | */ 71 | + (SDWebImagePrefetcher *)sharedImagePrefetcher; 72 | 73 | /** 74 | * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, 75 | * currently one image is downloaded at a time, 76 | * and skips images for failed downloads and proceed to the next image in the list 77 | * 78 | * @param urls list of URLs to prefetch 79 | */ 80 | - (void)prefetchURLs:(NSArray *)urls; 81 | 82 | /** 83 | * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, 84 | * currently one image is downloaded at a time, 85 | * and skips images for failed downloads and proceed to the next image in the list 86 | * 87 | * @param urls list of URLs to prefetch 88 | * @param progressBlock block to be called when progress updates; 89 | * first parameter is the number of completed (successful or not) requests, 90 | * second parameter is the total number of images originally requested to be prefetched 91 | * @param completionBlock block to be called when prefetching is completed 92 | * first param is the number of completed (successful or not) requests, 93 | * second parameter is the number of skipped requests 94 | */ 95 | - (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock; 96 | 97 | /** 98 | * Remove and cancel queued list 99 | */ 100 | - (void)cancelPrefetching; 101 | 102 | 103 | @end 104 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/SDWebImagePrefetcher.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 "SDWebImagePrefetcher.h" 10 | 11 | #if (!defined(DEBUG) && !defined (SD_VERBOSE)) || defined(SD_LOG_NONE) 12 | #define NSLog(...) 13 | #endif 14 | 15 | @interface SDWebImagePrefetcher () 16 | 17 | @property (strong, nonatomic) SDWebImageManager *manager; 18 | @property (strong, nonatomic) NSArray *prefetchURLs; 19 | @property (assign, nonatomic) NSUInteger requestedCount; 20 | @property (assign, nonatomic) NSUInteger skippedCount; 21 | @property (assign, nonatomic) NSUInteger finishedCount; 22 | @property (assign, nonatomic) NSTimeInterval startedTime; 23 | @property (copy, nonatomic) SDWebImagePrefetcherCompletionBlock completionBlock; 24 | @property (copy, nonatomic) SDWebImagePrefetcherProgressBlock progressBlock; 25 | 26 | @end 27 | 28 | @implementation SDWebImagePrefetcher 29 | 30 | + (SDWebImagePrefetcher *)sharedImagePrefetcher { 31 | static dispatch_once_t once; 32 | static id instance; 33 | dispatch_once(&once, ^{ 34 | instance = [self new]; 35 | }); 36 | return instance; 37 | } 38 | 39 | - (id)init { 40 | if ((self = [super init])) { 41 | _manager = [SDWebImageManager new]; 42 | _options = SDWebImageLowPriority; 43 | _prefetcherQueue = dispatch_get_main_queue(); 44 | self.maxConcurrentDownloads = 3; 45 | } 46 | return self; 47 | } 48 | 49 | - (void)setMaxConcurrentDownloads:(NSUInteger)maxConcurrentDownloads { 50 | self.manager.imageDownloader.maxConcurrentDownloads = maxConcurrentDownloads; 51 | } 52 | 53 | - (NSUInteger)maxConcurrentDownloads { 54 | return self.manager.imageDownloader.maxConcurrentDownloads; 55 | } 56 | 57 | - (void)startPrefetchingAtIndex:(NSUInteger)index { 58 | if (index >= self.prefetchURLs.count) return; 59 | self.requestedCount++; 60 | [self.manager downloadImageWithURL:self.prefetchURLs[index] options:self.options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { 61 | if (!finished) return; 62 | self.finishedCount++; 63 | 64 | if (image) { 65 | if (self.progressBlock) { 66 | self.progressBlock(self.finishedCount,[self.prefetchURLs count]); 67 | } 68 | NSLog(@"Prefetched %@ out of %@", @(self.finishedCount), @(self.prefetchURLs.count)); 69 | } 70 | else { 71 | if (self.progressBlock) { 72 | self.progressBlock(self.finishedCount,[self.prefetchURLs count]); 73 | } 74 | NSLog(@"Prefetched %@ out of %@ (Failed)", @(self.finishedCount), @(self.prefetchURLs.count)); 75 | 76 | // Add last failed 77 | self.skippedCount++; 78 | } 79 | if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didPrefetchURL:finishedCount:totalCount:)]) { 80 | [self.delegate imagePrefetcher:self 81 | didPrefetchURL:self.prefetchURLs[index] 82 | finishedCount:self.finishedCount 83 | totalCount:self.prefetchURLs.count 84 | ]; 85 | } 86 | if (self.prefetchURLs.count > self.requestedCount) { 87 | dispatch_async(self.prefetcherQueue, ^{ 88 | [self startPrefetchingAtIndex:self.requestedCount]; 89 | }); 90 | } 91 | else if (self.finishedCount == self.requestedCount) { 92 | [self reportStatus]; 93 | if (self.completionBlock) { 94 | self.completionBlock(self.finishedCount, self.skippedCount); 95 | self.completionBlock = nil; 96 | } 97 | self.progressBlock = nil; 98 | } 99 | }]; 100 | } 101 | 102 | - (void)reportStatus { 103 | NSUInteger total = [self.prefetchURLs count]; 104 | NSLog(@"Finished prefetching (%@ successful, %@ skipped, timeElasped %.2f)", @(total - self.skippedCount), @(self.skippedCount), CFAbsoluteTimeGetCurrent() - self.startedTime); 105 | if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didFinishWithTotalCount:skippedCount:)]) { 106 | [self.delegate imagePrefetcher:self 107 | didFinishWithTotalCount:(total - self.skippedCount) 108 | skippedCount:self.skippedCount 109 | ]; 110 | } 111 | } 112 | 113 | - (void)prefetchURLs:(NSArray *)urls { 114 | [self prefetchURLs:urls progress:nil completed:nil]; 115 | } 116 | 117 | - (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock { 118 | [self cancelPrefetching]; // Prevent duplicate prefetch request 119 | self.startedTime = CFAbsoluteTimeGetCurrent(); 120 | self.prefetchURLs = urls; 121 | self.completionBlock = completionBlock; 122 | self.progressBlock = progressBlock; 123 | 124 | if(urls.count == 0){ 125 | if(completionBlock){ 126 | completionBlock(0,0); 127 | } 128 | }else{ 129 | // Starts prefetching from the very first image on the list with the max allowed concurrency 130 | NSUInteger listCount = self.prefetchURLs.count; 131 | for (NSUInteger i = 0; i < self.maxConcurrentDownloads && self.requestedCount < listCount; i++) { 132 | [self startPrefetchingAtIndex:i]; 133 | } 134 | } 135 | } 136 | 137 | - (void)cancelPrefetching { 138 | self.prefetchURLs = nil; 139 | self.skippedCount = 0; 140 | self.requestedCount = 0; 141 | self.finishedCount = 0; 142 | [self.manager cancelAll]; 143 | } 144 | 145 | @end 146 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/UIImage+GIF.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+GIF.h 3 | // LBGIFImage 4 | // 5 | // Created by Laurin Brandner on 06.01.12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (GIF) 12 | 13 | + (UIImage *)sd_animatedGIFNamed:(NSString *)name; 14 | 15 | + (UIImage *)sd_animatedGIFWithData:(NSData *)data; 16 | 17 | - (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/UIImage+GIF.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+GIF.m 3 | // LBGIFImage 4 | // 5 | // Created by Laurin Brandner on 06.01.12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import "UIImage+GIF.h" 10 | #import 11 | 12 | @implementation UIImage (GIF) 13 | 14 | + (UIImage *)sd_animatedGIFWithData:(NSData *)data { 15 | if (!data) { 16 | return nil; 17 | } 18 | 19 | CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); 20 | 21 | size_t count = CGImageSourceGetCount(source); 22 | 23 | UIImage *animatedImage; 24 | 25 | if (count <= 1) { 26 | animatedImage = [[UIImage alloc] initWithData:data]; 27 | } 28 | else { 29 | NSMutableArray *images = [NSMutableArray array]; 30 | 31 | NSTimeInterval duration = 0.0f; 32 | 33 | for (size_t i = 0; i < count; i++) { 34 | CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL); 35 | 36 | duration += [self sd_frameDurationAtIndex:i source:source]; 37 | 38 | [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]]; 39 | 40 | CGImageRelease(image); 41 | } 42 | 43 | if (!duration) { 44 | duration = (1.0f / 10.0f) * count; 45 | } 46 | 47 | animatedImage = [UIImage animatedImageWithImages:images duration:duration]; 48 | } 49 | 50 | CFRelease(source); 51 | 52 | return animatedImage; 53 | } 54 | 55 | + (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source { 56 | float frameDuration = 0.1f; 57 | CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil); 58 | NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties; 59 | NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary]; 60 | 61 | NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime]; 62 | if (delayTimeUnclampedProp) { 63 | frameDuration = [delayTimeUnclampedProp floatValue]; 64 | } 65 | else { 66 | 67 | NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime]; 68 | if (delayTimeProp) { 69 | frameDuration = [delayTimeProp floatValue]; 70 | } 71 | } 72 | 73 | // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. 74 | // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify 75 | // a duration of <= 10 ms. See and 76 | // for more information. 77 | 78 | if (frameDuration < 0.011f) { 79 | frameDuration = 0.100f; 80 | } 81 | 82 | CFRelease(cfFrameProperties); 83 | return frameDuration; 84 | } 85 | 86 | + (UIImage *)sd_animatedGIFNamed:(NSString *)name { 87 | CGFloat scale = [UIScreen mainScreen].scale; 88 | 89 | if (scale > 1.0f) { 90 | NSString *retinaPath = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"gif"]; 91 | 92 | NSData *data = [NSData dataWithContentsOfFile:retinaPath]; 93 | 94 | if (data) { 95 | return [UIImage sd_animatedGIFWithData:data]; 96 | } 97 | 98 | NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"]; 99 | 100 | data = [NSData dataWithContentsOfFile:path]; 101 | 102 | if (data) { 103 | return [UIImage sd_animatedGIFWithData:data]; 104 | } 105 | 106 | return [UIImage imageNamed:name]; 107 | } 108 | else { 109 | NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"]; 110 | 111 | NSData *data = [NSData dataWithContentsOfFile:path]; 112 | 113 | if (data) { 114 | return [UIImage sd_animatedGIFWithData:data]; 115 | } 116 | 117 | return [UIImage imageNamed:name]; 118 | } 119 | } 120 | 121 | - (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size { 122 | if (CGSizeEqualToSize(self.size, size) || CGSizeEqualToSize(size, CGSizeZero)) { 123 | return self; 124 | } 125 | 126 | CGSize scaledSize = size; 127 | CGPoint thumbnailPoint = CGPointZero; 128 | 129 | CGFloat widthFactor = size.width / self.size.width; 130 | CGFloat heightFactor = size.height / self.size.height; 131 | CGFloat scaleFactor = (widthFactor > heightFactor) ? widthFactor : heightFactor; 132 | scaledSize.width = self.size.width * scaleFactor; 133 | scaledSize.height = self.size.height * scaleFactor; 134 | 135 | if (widthFactor > heightFactor) { 136 | thumbnailPoint.y = (size.height - scaledSize.height) * 0.5; 137 | } 138 | else if (widthFactor < heightFactor) { 139 | thumbnailPoint.x = (size.width - scaledSize.width) * 0.5; 140 | } 141 | 142 | NSMutableArray *scaledImages = [NSMutableArray array]; 143 | 144 | UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); 145 | 146 | for (UIImage *image in self.images) { 147 | [image drawInRect:CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)]; 148 | UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); 149 | 150 | [scaledImages addObject:newImage]; 151 | } 152 | 153 | UIGraphicsEndImageContext(); 154 | 155 | return [UIImage animatedImageWithImages:scaledImages duration:self.duration]; 156 | } 157 | 158 | @end 159 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/UIImage+MultiFormat.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+MultiFormat.h 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 07/06/13. 6 | // Copyright (c) 2013 Dailymotion. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIImage (MultiFormat) 12 | 13 | + (UIImage *)sd_imageWithData:(NSData *)data; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/UIImage+MultiFormat.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+MultiFormat.m 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 07/06/13. 6 | // Copyright (c) 2013 Dailymotion. All rights reserved. 7 | // 8 | 9 | #import "UIImage+MultiFormat.h" 10 | #import "UIImage+GIF.h" 11 | #import "NSData+ImageContentType.h" 12 | #import 13 | 14 | #ifdef SD_WEBP 15 | #import "UIImage+WebP.h" 16 | #endif 17 | 18 | @implementation UIImage (MultiFormat) 19 | 20 | + (UIImage *)sd_imageWithData:(NSData *)data { 21 | UIImage *image; 22 | NSString *imageContentType = [NSData sd_contentTypeForImageData:data]; 23 | if ([imageContentType isEqualToString:@"image/gif"]) { 24 | image = [UIImage sd_animatedGIFWithData:data]; 25 | } 26 | #ifdef SD_WEBP 27 | else if ([imageContentType isEqualToString:@"image/webp"]) 28 | { 29 | image = [UIImage sd_imageWithWebPData:data]; 30 | } 31 | #endif 32 | else { 33 | image = [[UIImage alloc] initWithData:data]; 34 | UIImageOrientation orientation = [self sd_imageOrientationFromImageData:data]; 35 | if (orientation != UIImageOrientationUp) { 36 | image = [UIImage imageWithCGImage:image.CGImage 37 | scale:image.scale 38 | orientation:orientation]; 39 | } 40 | } 41 | 42 | 43 | return image; 44 | } 45 | 46 | 47 | +(UIImageOrientation)sd_imageOrientationFromImageData:(NSData *)imageData { 48 | UIImageOrientation result = UIImageOrientationUp; 49 | CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL); 50 | if (imageSource) { 51 | CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL); 52 | if (properties) { 53 | CFTypeRef val; 54 | int exifOrientation; 55 | val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation); 56 | if (val) { 57 | CFNumberGetValue(val, kCFNumberIntType, &exifOrientation); 58 | result = [self sd_exifOrientationToiOSOrientation:exifOrientation]; 59 | } // else - if it's not set it remains at up 60 | CFRelease((CFTypeRef) properties); 61 | } else { 62 | //NSLog(@"NO PROPERTIES, FAIL"); 63 | } 64 | CFRelease(imageSource); 65 | } 66 | return result; 67 | } 68 | 69 | #pragma mark EXIF orientation tag converter 70 | // Convert an EXIF image orientation to an iOS one. 71 | // reference see here: http://sylvana.net/jpegcrop/exif_orientation.html 72 | + (UIImageOrientation) sd_exifOrientationToiOSOrientation:(int)exifOrientation { 73 | UIImageOrientation orientation = UIImageOrientationUp; 74 | switch (exifOrientation) { 75 | case 1: 76 | orientation = UIImageOrientationUp; 77 | break; 78 | 79 | case 3: 80 | orientation = UIImageOrientationDown; 81 | break; 82 | 83 | case 8: 84 | orientation = UIImageOrientationLeft; 85 | break; 86 | 87 | case 6: 88 | orientation = UIImageOrientationRight; 89 | break; 90 | 91 | case 2: 92 | orientation = UIImageOrientationUpMirrored; 93 | break; 94 | 95 | case 4: 96 | orientation = UIImageOrientationDownMirrored; 97 | break; 98 | 99 | case 5: 100 | orientation = UIImageOrientationLeftMirrored; 101 | break; 102 | 103 | case 7: 104 | orientation = UIImageOrientationRightMirrored; 105 | break; 106 | default: 107 | break; 108 | } 109 | return orientation; 110 | } 111 | 112 | 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/UIImage+WebP.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+WebP.h 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 07/06/13. 6 | // Copyright (c) 2013 Dailymotion. All rights reserved. 7 | // 8 | 9 | #ifdef SD_WEBP 10 | 11 | #import 12 | 13 | // Fix for issue #416 Undefined symbols for architecture armv7 since WebP introduction when deploying to device 14 | void WebPInitPremultiplyNEON(void); 15 | 16 | void WebPInitUpsamplersNEON(void); 17 | 18 | void VP8DspInitNEON(void); 19 | 20 | @interface UIImage (WebP) 21 | 22 | + (UIImage *)sd_imageWithWebPData:(NSData *)data; 23 | 24 | @end 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/UIImage+WebP.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+WebP.m 3 | // SDWebImage 4 | // 5 | // Created by Olivier Poitrey on 07/06/13. 6 | // Copyright (c) 2013 Dailymotion. All rights reserved. 7 | // 8 | 9 | #ifdef SD_WEBP 10 | #import "UIImage+WebP.h" 11 | #import "webp/decode.h" 12 | 13 | // Callback for CGDataProviderRelease 14 | static void FreeImageData(void *info, const void *data, size_t size) 15 | { 16 | free((void *)data); 17 | } 18 | 19 | @implementation UIImage (WebP) 20 | 21 | + (UIImage *)sd_imageWithWebPData:(NSData *)data { 22 | WebPDecoderConfig config; 23 | if (!WebPInitDecoderConfig(&config)) { 24 | return nil; 25 | } 26 | 27 | if (WebPGetFeatures(data.bytes, data.length, &config.input) != VP8_STATUS_OK) { 28 | return nil; 29 | } 30 | 31 | config.output.colorspace = config.input.has_alpha ? MODE_rgbA : MODE_RGB; 32 | config.options.use_threads = 1; 33 | 34 | // Decode the WebP image data into a RGBA value array. 35 | if (WebPDecode(data.bytes, data.length, &config) != VP8_STATUS_OK) { 36 | return nil; 37 | } 38 | 39 | int width = config.input.width; 40 | int height = config.input.height; 41 | if (config.options.use_scaling) { 42 | width = config.options.scaled_width; 43 | height = config.options.scaled_height; 44 | } 45 | 46 | // Construct a UIImage from the decoded RGBA value array. 47 | CGDataProviderRef provider = 48 | CGDataProviderCreateWithData(NULL, config.output.u.RGBA.rgba, config.output.u.RGBA.size, FreeImageData); 49 | CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); 50 | CGBitmapInfo bitmapInfo = config.input.has_alpha ? kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast : 0; 51 | size_t components = config.input.has_alpha ? 4 : 3; 52 | CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; 53 | CGImageRef imageRef = CGImageCreate(width, height, 8, components * 8, components * width, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); 54 | 55 | CGColorSpaceRelease(colorSpaceRef); 56 | CGDataProviderRelease(provider); 57 | 58 | UIImage *image = [[UIImage alloc] initWithCGImage:imageRef]; 59 | CGImageRelease(imageRef); 60 | 61 | return image; 62 | } 63 | 64 | @end 65 | 66 | #if !COCOAPODS 67 | // Functions to resolve some undefined symbols when using WebP and force_load flag 68 | void WebPInitPremultiplyNEON(void) {} 69 | void WebPInitUpsamplersNEON(void) {} 70 | void VP8DspInitNEON(void) {} 71 | #endif 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/UIImageView+HighlightedWebCache.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 10 | #import "SDWebImageCompat.h" 11 | #import "SDWebImageManager.h" 12 | 13 | /** 14 | * Integrates SDWebImage async downloading and caching of remote images with UIImageView for highlighted state. 15 | */ 16 | @interface UIImageView (HighlightedWebCache) 17 | 18 | /** 19 | * Set the imageView `highlightedImage` with an `url`. 20 | * 21 | * The download is asynchronous and cached. 22 | * 23 | * @param url The url for the image. 24 | */ 25 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url; 26 | 27 | /** 28 | * Set the imageView `highlightedImage` with an `url` and custom options. 29 | * 30 | * The download is asynchronous and cached. 31 | * 32 | * @param url The url for the image. 33 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 34 | */ 35 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options; 36 | 37 | /** 38 | * Set the imageView `highlightedImage` with an `url`. 39 | * 40 | * The download is asynchronous and cached. 41 | * 42 | * @param url The url for the image. 43 | * @param completedBlock A block called when operation has been completed. This block has no return value 44 | * and takes the requested UIImage as first parameter. In case of error the image parameter 45 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 46 | * indicating if the image was retrived from the local cache or from the network. 47 | * The fourth parameter is the original image url. 48 | */ 49 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; 50 | 51 | /** 52 | * Set the imageView `highlightedImage` with an `url` and custom options. 53 | * 54 | * The download is asynchronous and cached. 55 | * 56 | * @param url The url for the image. 57 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 58 | * @param completedBlock A block called when operation has been completed. This block has no return value 59 | * and takes the requested UIImage as first parameter. In case of error the image parameter 60 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 61 | * indicating if the image was retrived from the local cache or from the network. 62 | * The fourth parameter is the original image url. 63 | */ 64 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; 65 | 66 | /** 67 | * Set the imageView `highlightedImage` with an `url` and custom options. 68 | * 69 | * The download is asynchronous and cached. 70 | * 71 | * @param url The url for the image. 72 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. 73 | * @param progressBlock A block called while image is downloading 74 | * @param completedBlock A block called when operation has been completed. This block has no return value 75 | * and takes the requested UIImage as first parameter. In case of error the image parameter 76 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean 77 | * indicating if the image was retrived from the local cache or from the network. 78 | * The fourth parameter is the original image url. 79 | */ 80 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; 81 | 82 | /** 83 | * Cancel the current download 84 | */ 85 | - (void)sd_cancelCurrentHighlightedImageLoad; 86 | 87 | @end 88 | 89 | 90 | @interface UIImageView (HighlightedWebCacheDeprecated) 91 | 92 | - (void)setHighlightedImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:`"); 93 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:`"); 94 | - (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:completed:`"); 95 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:completed:`"); 96 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:progress:completed:`"); 97 | 98 | - (void)cancelCurrentHighlightedImageLoad __deprecated_msg("Use `sd_cancelCurrentHighlightedImageLoad`"); 99 | 100 | @end 101 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/UIImageView+HighlightedWebCache.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 "UIImageView+HighlightedWebCache.h" 10 | #import "UIView+WebCacheOperation.h" 11 | 12 | #define UIImageViewHighlightedWebCacheOperationKey @"highlightedImage" 13 | 14 | @implementation UIImageView (HighlightedWebCache) 15 | 16 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url { 17 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil]; 18 | } 19 | 20 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options { 21 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil]; 22 | } 23 | 24 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock { 25 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock]; 26 | } 27 | 28 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { 29 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock]; 30 | } 31 | 32 | - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { 33 | [self sd_cancelCurrentHighlightedImageLoad]; 34 | 35 | if (url) { 36 | __weak __typeof(self)wself = self; 37 | id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { 38 | if (!wself) return; 39 | dispatch_main_sync_safe (^ 40 | { 41 | if (!wself) return; 42 | if (image) { 43 | wself.highlightedImage = image; 44 | [wself setNeedsLayout]; 45 | } 46 | if (completedBlock && finished) { 47 | completedBlock(image, error, cacheType, url); 48 | } 49 | }); 50 | }]; 51 | [self sd_setImageLoadOperation:operation forKey:UIImageViewHighlightedWebCacheOperationKey]; 52 | } else { 53 | dispatch_main_async_safe(^{ 54 | NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; 55 | if (completedBlock) { 56 | completedBlock(nil, error, SDImageCacheTypeNone, url); 57 | } 58 | }); 59 | } 60 | } 61 | 62 | - (void)sd_cancelCurrentHighlightedImageLoad { 63 | [self sd_cancelImageLoadOperationWithKey:UIImageViewHighlightedWebCacheOperationKey]; 64 | } 65 | 66 | @end 67 | 68 | 69 | @implementation UIImageView (HighlightedWebCacheDeprecated) 70 | 71 | - (void)setHighlightedImageWithURL:(NSURL *)url { 72 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil]; 73 | } 74 | 75 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options { 76 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil]; 77 | } 78 | 79 | - (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock { 80 | [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 81 | if (completedBlock) { 82 | completedBlock(image, error, cacheType); 83 | } 84 | }]; 85 | } 86 | 87 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { 88 | [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 89 | if (completedBlock) { 90 | completedBlock(image, error, cacheType); 91 | } 92 | }]; 93 | } 94 | 95 | - (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock { 96 | [self sd_setHighlightedImageWithURL:url options:0 progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { 97 | if (completedBlock) { 98 | completedBlock(image, error, cacheType); 99 | } 100 | }]; 101 | } 102 | 103 | - (void)cancelCurrentHighlightedImageLoad { 104 | [self sd_cancelCurrentHighlightedImageLoad]; 105 | } 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/UIView+WebCacheOperation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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 10 | #import "SDWebImageManager.h" 11 | 12 | @interface UIView (WebCacheOperation) 13 | 14 | /** 15 | * Set the image load operation (storage in a UIView based dictionary) 16 | * 17 | * @param operation the operation 18 | * @param key key for storing the operation 19 | */ 20 | - (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key; 21 | 22 | /** 23 | * Cancel all operations for the current UIView and key 24 | * 25 | * @param key key for identifying the operations 26 | */ 27 | - (void)sd_cancelImageLoadOperationWithKey:(NSString *)key; 28 | 29 | /** 30 | * Just remove the operations corresponding to the current UIView and key without cancelling them 31 | * 32 | * @param key key for identifying the operations 33 | */ 34 | - (void)sd_removeImageLoadOperationWithKey:(NSString *)key; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Lib/SDWebImage/UIView+WebCacheOperation.m: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the SDWebImage package. 3 | * (c) Olivier Poitrey 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+WebCacheOperation.h" 10 | #import "objc/runtime.h" 11 | 12 | static char loadOperationKey; 13 | 14 | @implementation UIView (WebCacheOperation) 15 | 16 | - (NSMutableDictionary *)operationDictionary { 17 | NSMutableDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey); 18 | if (operations) { 19 | return operations; 20 | } 21 | operations = [NSMutableDictionary dictionary]; 22 | objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 23 | return operations; 24 | } 25 | 26 | - (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key { 27 | [self sd_cancelImageLoadOperationWithKey:key]; 28 | NSMutableDictionary *operationDictionary = [self operationDictionary]; 29 | [operationDictionary setObject:operation forKey:key]; 30 | } 31 | 32 | - (void)sd_cancelImageLoadOperationWithKey:(NSString *)key { 33 | // Cancel in progress downloader from queue 34 | NSMutableDictionary *operationDictionary = [self operationDictionary]; 35 | id operations = [operationDictionary objectForKey:key]; 36 | if (operations) { 37 | if ([operations isKindOfClass:[NSArray class]]) { 38 | for (id operation in operations) { 39 | if (operation) { 40 | [operation cancel]; 41 | } 42 | } 43 | } else if ([operations conformsToProtocol:@protocol(SDWebImageOperation)]){ 44 | [(id) operations cancel]; 45 | } 46 | [operationDictionary removeObjectForKey:key]; 47 | } 48 | } 49 | 50 | - (void)sd_removeImageLoadOperationWithKey:(NSString *)key { 51 | NSMutableDictionary *operationDictionary = [self operationDictionary]; 52 | [operationDictionary removeObjectForKey:key]; 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /JLPhotoBrowser/Picture.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | http://imgsrc.baidu.com/forum/w%3D580/sign=fd6c6565c1cec3fd8b3ea77de689d4b6/3eb24034970a304e61613853d3c8a786c8175c01.jpg 6 | http://imgsrc.baidu.com/forum/pic/item/b812c8fcc3cec3fdd7f532ead688d43f86942761.jpg 7 | http://images.17173.com/2012/news/2012/11/28/2012cpb1128hy33s.jpg 8 | http://c.hiphotos.baidu.com/zhidao/pic/item/5ab5c9ea15ce36d3dfdcf9a93af33a87e850b14a.jpg 9 | http://img15.3lian.com/2015/f3/09/d/102.jpg 10 | http://pic.5442.com/2013/0106/01/09.jpg 11 | http://b.hiphotos.baidu.com/zhidao/pic/item/b90e7bec54e736d18e47675e99504fc2d5626914.jpg 12 | http://d.hiphotos.baidu.com/zhidao/pic/item/267f9e2f07082838e4def51dba99a9014d08f1ec.jpg 13 | http://5.66825.com/download/pic/000/327/b9fa7606a12d5cd5aa08665e4900eee3.jpg 14 | 15 | 16 | -------------------------------------------------------------------------------- /JLPhotoBrowser/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // JLPhotoBrowser 4 | // 5 | // Created by liao on 15/12/24. 6 | // Copyright © 2015年 BangGu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /JLPhotoBrowser/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // JLPhotoBrowser 4 | // 5 | // Created by liao on 15/12/24. 6 | // Copyright © 2015年 BangGu. All rights reserved. 7 | // 8 | 9 | //屏幕宽 10 | #define kScreenWidth [UIScreen mainScreen].bounds.size.width 11 | #define kScreenHeight [UIScreen mainScreen].bounds.size.height 12 | #define kCellHeight 64 13 | #define kLineHeight 0.5 14 | #define kTintColor [UIColor colorWithRed:82.0/255.0 green:82.0/255.0 blue:82.0/255.0 alpha:1.0] 15 | 16 | #import "ViewController.h" 17 | #import "JLNetworkViewController.h" 18 | #import "JLAlbumViewController.h" 19 | 20 | NSString *const kNetworkPhotoBrowser = @"网络图片浏览"; 21 | NSString *const kAlbumPicker = @"访问本地相册"; 22 | 23 | @interface ViewController () 24 | 25 | @end 26 | 27 | @implementation ViewController 28 | 29 | - (void)viewDidLoad { 30 | 31 | [super viewDidLoad]; 32 | 33 | self.navigationController.navigationBar.tintColor = kTintColor; 34 | 35 | } 36 | 37 | #pragma mark - UITableViewDelegate 38 | 39 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 40 | return 2; 41 | } 42 | 43 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 44 | return kCellHeight; 45 | } 46 | 47 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 48 | 49 | static NSString *reuseIdentifier = @"reuseIdentifier"; 50 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier]; 51 | if (!cell) { 52 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]; 53 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 54 | //底部黑线 55 | CALayer *line = [CALayer layer]; 56 | line.backgroundColor = [UIColor colorWithRed:199.0/255.0 green:199.0/255.0 blue:204.0/255.0 alpha:1.0].CGColor; 57 | line.position = CGPointMake(10, kCellHeight-kLineHeight); 58 | line.anchorPoint = CGPointMake(0, 0); 59 | line.bounds = CGRectMake(0, 0,kScreenWidth-line.position.x, 0.5); 60 | [cell.layer addSublayer:line]; 61 | } 62 | 63 | NSString *decription = nil; 64 | 65 | if (indexPath.row==0) { 66 | decription = kNetworkPhotoBrowser; 67 | }else{ 68 | decription = kAlbumPicker; 69 | } 70 | 71 | NSDictionary *Attributes = @{NSForegroundColorAttributeName:[UIColor blackColor],NSFontAttributeName:[UIFont boldSystemFontOfSize:17.0]}; 72 | NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:decription attributes:Attributes]; 73 | 74 | cell.textLabel.attributedText = attStr; 75 | 76 | return cell; 77 | 78 | } 79 | 80 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ 81 | 82 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 83 | 84 | switch (indexPath.row) { 85 | case 0: 86 | { 87 | JLNetworkViewController *networkVc = [[JLNetworkViewController alloc] init]; 88 | networkVc.title = kNetworkPhotoBrowser; 89 | [self.navigationController pushViewController:networkVc animated:YES]; 90 | } 91 | break; 92 | case 1: 93 | { 94 | JLAlbumViewController *albumVc = [[JLAlbumViewController alloc] init]; 95 | albumVc.title = kAlbumPicker; 96 | [self.navigationController pushViewController:albumVc animated:YES]; 97 | } 98 | break; 99 | 100 | default: 101 | break; 102 | } 103 | 104 | 105 | } 106 | 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /JLPhotoBrowser/imgs/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/imgs/1.jpg -------------------------------------------------------------------------------- /JLPhotoBrowser/imgs/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/imgs/2.jpg -------------------------------------------------------------------------------- /JLPhotoBrowser/imgs/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/imgs/3.jpg -------------------------------------------------------------------------------- /JLPhotoBrowser/imgs/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/imgs/4.jpg -------------------------------------------------------------------------------- /JLPhotoBrowser/imgs/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/imgs/5.jpg -------------------------------------------------------------------------------- /JLPhotoBrowser/imgs/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/imgs/6.jpg -------------------------------------------------------------------------------- /JLPhotoBrowser/imgs/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/imgs/7.jpg -------------------------------------------------------------------------------- /JLPhotoBrowser/imgs/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/imgs/8.jpg -------------------------------------------------------------------------------- /JLPhotoBrowser/imgs/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/imgs/9.jpg -------------------------------------------------------------------------------- /JLPhotoBrowser/imgs/preview_image_failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/imgs/preview_image_failure.png -------------------------------------------------------------------------------- /JLPhotoBrowser/imgs/preview_image_failure@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JlongTian/JLPhotoBrowser/88805749086be0e5d1eea417b566d55e666dd35b/JLPhotoBrowser/imgs/preview_image_failure@2x.png -------------------------------------------------------------------------------- /JLPhotoBrowser/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // JLPhotoBrowser 4 | // 5 | // Created by liao on 15/12/24. 6 | // Copyright © 2015年 BangGu. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /JLPhotoBrowserTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /JLPhotoBrowserTests/JLPhotoBrowserTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLPhotoBrowserTests.m 3 | // JLPhotoBrowserTests 4 | // 5 | // Created by liao on 15/12/24. 6 | // Copyright © 2015年 BangGu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JLPhotoBrowserTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation JLPhotoBrowserTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /JLPhotoBrowserUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /JLPhotoBrowserUITests/JLPhotoBrowserUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // JLPhotoBrowserUITests.m 3 | // JLPhotoBrowserUITests 4 | // 5 | // Created by liao on 15/12/24. 6 | // Copyright © 2015年 BangGu. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface JLPhotoBrowserUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation JLPhotoBrowserUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JLPhotoBrowser 2 | 一款简单的图片浏览器 3 | 用法示例: 4 | ```Objective-C 5 | NSMutableArray *photos = [NSMutableArray array]; 6 | 7 | for (int i=0; i