├── README.md
├── ZZPhotoKit.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ ├── Dev.z.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ │ ├── Migic_Z.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ │ └── Yuan.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ ├── Dev.z.xcuserdatad
│ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ │ ├── ZZPhotoKit.xcscheme
│ │ └── xcschememanagement.plist
│ ├── Migic_Z.xcuserdatad
│ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ │ ├── ZZPhotoKit.xcscheme
│ │ └── xcschememanagement.plist
│ └── Yuan.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── ZZPhotoKit.xcscheme
│ └── xcschememanagement.plist
├── ZZPhotoKit
├── .DS_Store
├── AppDelegate.h
├── AppDelegate.m
├── Assets.xcassets
│ ├── .DS_Store
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Base.lproj
│ └── LaunchScreen.storyboard
├── Info.plist
├── PicsCell.h
├── PicsCell.m
├── Resources
│ ├── scv1.jpg
│ ├── scv2.jpg
│ ├── scv3.jpg
│ ├── scv4.jpg
│ └── scv5.jpg
├── SDWebImage
│ ├── .DS_Store
│ ├── 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
├── SVProgressHUD
│ └── .DS_Store
├── ViewController.h
├── ViewController.m
├── ZZPhotoKit
│ ├── Public
│ │ ├── Other
│ │ │ ├── ZZAlumAnimation.h
│ │ │ └── ZZAlumAnimation.m
│ │ ├── Resources
│ │ │ ├── back_button_normal.png
│ │ │ ├── back_button_normal@2x.png
│ │ │ ├── camera_focus_pic.png
│ │ │ ├── change_camera_pic.png
│ │ │ ├── flash_close_pic.png
│ │ │ ├── flash_open_pic.png
│ │ │ ├── no_data.png
│ │ │ ├── photo_add.png
│ │ │ ├── remove_btn_pic.png
│ │ │ ├── select_no.png
│ │ │ ├── select_yes.png
│ │ │ ├── take_photo_pic.png
│ │ │ ├── take_photo_pic@2x.png
│ │ │ ├── trash_btn_pic.png
│ │ │ └── zz_alumb_rightCell.png
│ │ └── ZZResourceConfig.h
│ ├── ZZBrowser
│ │ ├── ZZBrowserPickerCell.h
│ │ ├── ZZBrowserPickerCell.m
│ │ ├── ZZBrowserPickerViewController.h
│ │ ├── ZZBrowserPickerViewController.m
│ │ ├── ZZPageControl.h
│ │ └── ZZPageControl.m
│ ├── ZZCamera
│ │ ├── Controller
│ │ │ ├── ZZCameraBrowerViewController.h
│ │ │ ├── ZZCameraBrowerViewController.m
│ │ │ ├── ZZCameraController.h
│ │ │ ├── ZZCameraController.m
│ │ │ ├── ZZCameraPickerViewController.h
│ │ │ └── ZZCameraPickerViewController.m
│ │ ├── Model
│ │ │ ├── ZZCamera.h
│ │ │ └── ZZCamera.m
│ │ └── View
│ │ │ ├── ZZCameraBrowerCell.h
│ │ │ ├── ZZCameraBrowerCell.m
│ │ │ ├── ZZCameraFocusView.h
│ │ │ ├── ZZCameraFocusView.m
│ │ │ ├── ZZCameraPickerCell.h
│ │ │ └── ZZCameraPickerCell.m
│ ├── ZZPhoto
│ │ ├── Controller
│ │ │ ├── ZZPhotoBrowerViewController.h
│ │ │ ├── ZZPhotoBrowerViewController.m
│ │ │ ├── ZZPhotoController.h
│ │ │ ├── ZZPhotoController.m
│ │ │ ├── ZZPhotoListViewController.h
│ │ │ ├── ZZPhotoListViewController.m
│ │ │ ├── ZZPhotoPickerViewController.h
│ │ │ └── ZZPhotoPickerViewController.m
│ │ ├── Model
│ │ │ ├── ZZPhoto.h
│ │ │ ├── ZZPhoto.m
│ │ │ ├── ZZPhotoDatas.h
│ │ │ ├── ZZPhotoDatas.m
│ │ │ ├── ZZPhotoListModel.h
│ │ │ └── ZZPhotoListModel.m
│ │ └── View
│ │ │ ├── ZZPhotoAlert.h
│ │ │ ├── ZZPhotoAlert.m
│ │ │ ├── ZZPhotoBrowerCell.h
│ │ │ ├── ZZPhotoBrowerCell.m
│ │ │ ├── ZZPhotoHud.h
│ │ │ ├── ZZPhotoHud.m
│ │ │ ├── ZZPhotoListCell.h
│ │ │ ├── ZZPhotoListCell.m
│ │ │ ├── ZZPhotoPickerCell.h
│ │ │ ├── ZZPhotoPickerCell.m
│ │ │ ├── ZZPhotoPickerFooterView.h
│ │ │ └── ZZPhotoPickerFooterView.m
│ └── ZZPhotoKit.h
└── main.m
├── ZZPhotoKitTests
├── Info.plist
└── ZZPhotoKitTests.m
├── ZZPhotoKitUITests
├── Info.plist
└── ZZPhotoKitUITests.m
└── image
├── demonstrate.gif
├── examplepic.png
├── object.png
├── privacy_use.png
└── zz_camera_intro.jpg
/README.md:
--------------------------------------------------------------------------------
1 | # ZZPhotoKit
2 | ##说明
3 |
4 | * 此开源目前接近于成熟状态,不喜欢的大神们还望轻虐。
5 | * 注意此框架只支持 IOS 8.0 及以上系统使用。
6 | * 注意由于工作原因后续不做IOS7适配了,IOS7占有率也比较低了,所以也不考虑后续再做了。
7 | * 这次升级了版本之后以后可能不会有太大变动的。
8 | * 相册多选基于最新的 Photos 框架。
9 | * 相机连续拍摄基于AVFundation 框架。
10 | * 图片浏览器支持 SDWebImage 加载图片
11 | * 欢迎大家使用,欢迎大家Star
12 |
13 | ###告诉我您的APP,使用到我框架的把APP名字告诉我,谢谢哦。单纯看看使用率。(*^__^*)
14 | ###有什么不明白的地方,或者哪里需要改进的可以联系我
15 | ###联系方式
16 | ###关注微博:袁亮_
17 |
18 | ##项目介绍
19 | 
20 | 
21 |
22 | ##更新内容
23 |
24 | * 10月13日更新内容:网友提出意见,图片浏览器加入放大缩小手势。点击放大缩小下一版本添加。
25 | * 10月13日更新内容:相册多选中加入图片预览功能。
26 | * 10月12日更新内容:对不起同志们,框架中有内存暴增问题,今日发现已经解决。在使用的同志们看见后尽快更改一下吧。或者升级一下。
27 | * 逐步加入autolayout布局。一步一步走向横屏设备。
28 | * iOS 10适配框架
29 | * info.plist文件中添加相册与相机的权限
30 | * 相册权限 Privacy - Photo Library Usage Description
31 | * 相机权限 Privacy - Camera Usage Description
32 | * 在iOS 10 使用时,如不添加如上权限则会导致崩溃闪退。
33 | 
34 |
35 | ##使用方法
36 |
37 | 首先重要提醒一个 文件,ZZResourceConfig.h 这个配置文件。
38 | ###包含内容
39 |
40 | * 1.包含了所有的按钮图片信息,任意更换即可.
41 | * 2.包含了图片返回类型的公共枚举.
42 | * 3.所有用到的头文件。以及一些颜色、控制器宽高、屏幕宽高宏定义.
43 |
44 | ### 导入头文件
45 | ###import "ZZPhotoKit.h"
46 |
47 | * 相册多选的调用
48 | ```
49 | ZZPhotoController *photoController = [[ZZPhotoController alloc]init];
50 |
51 | //设置最大选择张数
52 | photoController.selectPhotoOfMax = 5;
53 |
54 | [photoController showIn:self result:^(id responseObject){
55 | //responseObject 中元素类型为 ZZPhoto
56 | //返回结果集
57 | NSLog(@"%@",responseObject);
58 | NSArray *array = (NSArray *)responseObject;
59 |
60 | }];
61 | ```
62 |
63 | * 相机连拍的调用
64 | ```
65 | ZZCameraController *cameraController = [[ZZCameraController alloc]init];
66 | //设置最大连拍张数
67 | cameraController.takePhotoOfMax = 8;
68 | //设置图片返回类型 (下面例子为缩略图)
69 | cameraController.imageType = ZZImageTypeOfThumb;
70 | [cameraController showIn:self result:^(id responseObject){
71 | //responseObject 中元素类型为 ZZCamera
72 | //返回结果集
73 | NSLog(@"%@",responseObject);
74 | NSArray *array = (NSArray *)responseObject;
75 | }];
76 |
77 | ```
78 | ### 新增model查看
79 | * 
80 | * 
81 |
82 | * 简单的图片浏览器
83 | ```
84 | ZZBrowserPickerViewController *browserController = [[ZZBrowserPickerViewController alloc]init];
85 | browserController.delegate = self;
86 | [browserController showIn:self animation:ShowAnimationOfPush];
87 |
88 | //delegate
89 | //图片的个数。
90 | -(NSInteger)zzbrowserPickerPhotoNum:(ZZBrowserPickerViewController *)controller
91 | //图片的数组。
92 | -(NSArray *)zzbrowserPickerPhotoContent:(ZZBrowserPickerViewController *)controller
93 | ```
94 |
95 | ###详细使用方法还是看demo 吧。
96 |
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/project.xcworkspace/xcuserdata/Dev.z.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit.xcodeproj/project.xcworkspace/xcuserdata/Dev.z.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/project.xcworkspace/xcuserdata/Migic_Z.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit.xcodeproj/project.xcworkspace/xcuserdata/Migic_Z.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/project.xcworkspace/xcuserdata/Yuan.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit.xcodeproj/project.xcworkspace/xcuserdata/Yuan.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/xcuserdata/Dev.z.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/xcuserdata/Dev.z.xcuserdatad/xcschemes/ZZPhotoKit.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 |
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/xcuserdata/Dev.z.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ZZPhotoKit.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 1C94AC011C3A7B1E00B26FAE
16 |
17 | primary
18 |
19 |
20 | 1C94AC1A1C3A7B1F00B26FAE
21 |
22 | primary
23 |
24 |
25 | 1C94AC251C3A7B1F00B26FAE
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/xcuserdata/Migic_Z.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/xcuserdata/Migic_Z.xcuserdatad/xcschemes/ZZPhotoKit.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 |
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/xcuserdata/Migic_Z.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ZZPhotoKit.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 1C94AC011C3A7B1E00B26FAE
16 |
17 | primary
18 |
19 |
20 | 1C94AC1A1C3A7B1F00B26FAE
21 |
22 | primary
23 |
24 |
25 | 1C94AC251C3A7B1F00B26FAE
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/xcuserdata/Yuan.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/xcuserdata/Yuan.xcuserdatad/xcschemes/ZZPhotoKit.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 |
--------------------------------------------------------------------------------
/ZZPhotoKit.xcodeproj/xcuserdata/Yuan.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | ZZPhotoKit.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 1C94AC011C3A7B1E00B26FAE
16 |
17 | primary
18 |
19 |
20 | 1C94AC1A1C3A7B1F00B26FAE
21 |
22 | primary
23 |
24 |
25 | 1C94AC251C3A7B1F00B26FAE
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/ZZPhotoKit/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/.DS_Store
--------------------------------------------------------------------------------
/ZZPhotoKit/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // ZZPhotoKit
4 | //
5 | // Created by Yuan on 16/1/4.
6 | // Copyright © 2016年 Ace. 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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // ZZPhotoKit
4 | //
5 | // Created by Yuan on 16/1/4.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "ViewController.h"
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 |
20 | UIImage *navBarBgImage = [self imageWithColor:[UIColor redColor]];
21 |
22 | [[UINavigationBar appearance] setBackgroundImage:navBarBgImage forBarMetrics:UIBarMetricsDefault];
23 |
24 | [[UINavigationBar appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor],NSForegroundColorAttributeName,[UIFont systemFontOfSize:18.0f],NSFontAttributeName,nil]];
25 |
26 | // Override point for customization after application launch.
27 | self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
28 |
29 | self.window.backgroundColor = [UIColor whiteColor];
30 |
31 |
32 | ViewController *mainViewController = [[ViewController alloc]initWithNibName:nil bundle:nil];
33 |
34 | UINavigationController *navi = [[UINavigationController alloc]initWithRootViewController:mainViewController];
35 | self.window.rootViewController = navi;
36 | [self.window makeKeyAndVisible];
37 | return YES;
38 | }
39 |
40 | -(UIImage *)imageWithColor:(UIColor *)color
41 | {
42 | CGRect rect = CGRectMake(0, 0, 1, 1);
43 | UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0);
44 | CGContextRef context = UIGraphicsGetCurrentContext();
45 | CGContextSetFillColorWithColor(context, [color CGColor]);
46 | CGContextFillRect(context, rect);
47 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
48 | UIGraphicsEndImageContext();
49 | return image;
50 | }
51 |
52 | - (void)applicationWillResignActive:(UIApplication *)application {
53 | // 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.
54 | // 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.
55 | }
56 |
57 | - (void)applicationDidEnterBackground:(UIApplication *)application {
58 | // 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.
59 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
60 | }
61 |
62 | - (void)applicationWillEnterForeground:(UIApplication *)application {
63 | // 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.
64 | }
65 |
66 | - (void)applicationDidBecomeActive:(UIApplication *)application {
67 | // 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.
68 | }
69 |
70 | - (void)applicationWillTerminate:(UIApplication *)application {
71 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
72 | }
73 |
74 | @end
75 |
--------------------------------------------------------------------------------
/ZZPhotoKit/Assets.xcassets/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/Assets.xcassets/.DS_Store
--------------------------------------------------------------------------------
/ZZPhotoKit/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 | }
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ZZPhotoKit
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | LSRequiresIPhoneOS
24 |
25 | NSAppTransportSecurity
26 |
27 | NSAllowsArbitraryLoads
28 |
29 |
30 | NSCameraUsageDescription
31 | 是否开启相机权限
32 | NSPhotoLibraryUsageDescription
33 | 是否开启相册权限
34 | UILaunchStoryboardName
35 | LaunchScreen
36 | UIRequiredDeviceCapabilities
37 |
38 | armv7
39 |
40 | UISupportedInterfaceOrientations
41 |
42 | UIInterfaceOrientationPortrait
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/ZZPhotoKit/PicsCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // PicsCell.h
3 | // ZZPhotoKit
4 | //
5 | // Created by Yuan on 16/1/13.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface PicsCell : UICollectionViewCell
12 |
13 | @property(strong,nonatomic) UIImageView *photo;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/ZZPhotoKit/PicsCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // PicsCell.m
3 | // ZZPhotoKit
4 | //
5 | // Created by Yuan on 16/1/13.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "PicsCell.h"
10 |
11 | @implementation PicsCell
12 |
13 | -(instancetype)initWithFrame:(CGRect)frame
14 | {
15 | self = [super initWithFrame:frame];
16 | if (self) {
17 | CGFloat photoSize = ([UIScreen mainScreen].bounds.size.width - 50) / 3;
18 |
19 | _photo = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, photoSize, photoSize)];
20 |
21 | _photo.layer.masksToBounds = YES;
22 |
23 | _photo.contentMode = UIViewContentModeScaleAspectFill;
24 |
25 | [self.contentView addSubview:_photo];
26 | }
27 | return self;
28 | }
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/ZZPhotoKit/Resources/scv1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/Resources/scv1.jpg
--------------------------------------------------------------------------------
/ZZPhotoKit/Resources/scv2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/Resources/scv2.jpg
--------------------------------------------------------------------------------
/ZZPhotoKit/Resources/scv3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/Resources/scv3.jpg
--------------------------------------------------------------------------------
/ZZPhotoKit/Resources/scv4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/Resources/scv4.jpg
--------------------------------------------------------------------------------
/ZZPhotoKit/Resources/scv5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/Resources/scv5.jpg
--------------------------------------------------------------------------------
/ZZPhotoKit/SDWebImage/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/SDWebImage/.DS_Store
--------------------------------------------------------------------------------
/ZZPhotoKit/SDWebImage/MKAnnotationView+WebCache.h:
--------------------------------------------------------------------------------
1 | //
2 | // MKAnnotationView+WebCache.h
3 | // SDWebImage
4 | //
5 | // Created by Olivier Poitrey on 14/03/12.
6 | // Copyright (c) 2012 Dailymotion. All rights reserved.
7 | //
8 |
9 | #import "MapKit/MapKit.h"
10 | #import "SDWebImageManager.h"
11 |
12 | /**
13 | * Integrates SDWebImage async downloading and caching of remote images with MKAnnotationView.
14 | */
15 | @interface MKAnnotationView (WebCache)
16 |
17 | /**
18 | * Get the current image URL.
19 | *
20 | * Note that because of the limitations of categories this property can get out of sync
21 | * if you use sd_setImage: directly.
22 | */
23 | - (NSURL *)sd_imageURL;
24 |
25 | /**
26 | * Set the imageView `image` with an `url`.
27 | *
28 | * The download is asynchronous and cached.
29 | *
30 | * @param url The url for the image.
31 | */
32 | - (void)sd_setImageWithURL:(NSURL *)url;
33 |
34 | /**
35 | * Set the imageView `image` with an `url` and a placeholder.
36 | *
37 | * The download is asynchronous and cached.
38 | *
39 | * @param url The url for the image.
40 | * @param placeholder The image to be set initially, until the image request finishes.
41 | * @see sd_setImageWithURL:placeholderImage:options:
42 | */
43 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
44 |
45 | /**
46 | * Set the imageView `image` with an `url`, placeholder and custom options.
47 | *
48 | * The download is asynchronous and cached.
49 | *
50 | * @param url The url for the image.
51 | * @param placeholder The image to be set initially, until the image request finishes.
52 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
53 | */
54 |
55 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;
56 |
57 | /**
58 | * Set the imageView `image` with an `url`.
59 | *
60 | * The download is asynchronous and cached.
61 | *
62 | * @param url The url for the image.
63 | * @param completedBlock A block called when operation has been completed. This block has no return value
64 | * and takes the requested UIImage as first parameter. In case of error the image parameter
65 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
66 | * indicating if the image was retrived from the local cache or from the network.
67 | * The fourth parameter is the original image url.
68 | */
69 | - (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;
70 |
71 | /**
72 | * Set the imageView `image` with an `url`, placeholder.
73 | *
74 | * The download is asynchronous and cached.
75 | *
76 | * @param url The url for the image.
77 | * @param placeholder The image to be set initially, until the image request finishes.
78 | * @param completedBlock A block called when operation has been completed. This block has no return value
79 | * and takes the requested UIImage as first parameter. In case of error the image parameter
80 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
81 | * indicating if the image was retrived from the local cache or from the network.
82 | * The fourth parameter is the original image url.
83 | */
84 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;
85 |
86 | /**
87 | * Set the imageView `image` with an `url`, placeholder and custom options.
88 | *
89 | * The download is asynchronous and cached.
90 | *
91 | * @param url The url for the image.
92 | * @param placeholder The image to be set initially, until the image request finishes.
93 | * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
94 | * @param completedBlock A block called when operation has been completed. This block has no return value
95 | * and takes the requested UIImage as first parameter. In case of error the image parameter
96 | * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
97 | * indicating if the image was retrived from the local cache or from the network.
98 | * The fourth parameter is the original image url.
99 | */
100 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
101 |
102 | /**
103 | * Cancel the current download
104 | */
105 | - (void)sd_cancelCurrentImageLoad;
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 MKAnnotationView *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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/SDWebImage/SDImageCache.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 |
12 | typedef NS_ENUM(NSInteger, SDImageCacheType) {
13 | /**
14 | * The image wasn't available the SDWebImage caches, but was downloaded from the web.
15 | */
16 | SDImageCacheTypeNone,
17 | /**
18 | * The image was obtained from the disk cache.
19 | */
20 | SDImageCacheTypeDisk,
21 | /**
22 | * The image was obtained from the memory cache.
23 | */
24 | SDImageCacheTypeMemory
25 | };
26 |
27 | typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType cacheType);
28 |
29 | typedef void(^SDWebImageCheckCacheCompletionBlock)(BOOL isInCache);
30 |
31 | typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize);
32 |
33 | /**
34 | * SDImageCache maintains a memory cache and an optional disk cache. Disk cache write operations are performed
35 | * asynchronous so it doesn’t add unnecessary latency to the UI.
36 | */
37 | @interface SDImageCache : NSObject
38 |
39 | /**
40 | * The maximum "total cost" of the in-memory image cache. The cost function is the number of pixels held in memory.
41 | */
42 | @property (assign, nonatomic) NSUInteger maxMemoryCost;
43 |
44 | /**
45 | * The maximum length of time to keep an image in the cache, in seconds
46 | */
47 | @property (assign, nonatomic) NSInteger maxCacheAge;
48 |
49 | /**
50 | * The maximum size of the cache, in bytes.
51 | */
52 | @property (assign, nonatomic) NSUInteger maxCacheSize;
53 |
54 | /**
55 | * Returns global shared cache instance
56 | *
57 | * @return SDImageCache global instance
58 | */
59 | + (SDImageCache *)sharedImageCache;
60 |
61 | /**
62 | * Init a new cache store with a specific namespace
63 | *
64 | * @param ns The namespace to use for this cache store
65 | */
66 | - (id)initWithNamespace:(NSString *)ns;
67 |
68 | /**
69 | * Add a read-only cache path to search for images pre-cached by SDImageCache
70 | * Useful if you want to bundle pre-loaded images with your app
71 | *
72 | * @param path The path to use for this read-only cache path
73 | */
74 | - (void)addReadOnlyCachePath:(NSString *)path;
75 |
76 | /**
77 | * Store an image into memory and disk cache at the given key.
78 | *
79 | * @param image The image to store
80 | * @param key The unique image cache key, usually it's image absolute URL
81 | */
82 | - (void)storeImage:(UIImage *)image forKey:(NSString *)key;
83 |
84 | /**
85 | * Store an image into memory and optionally disk cache at the given key.
86 | *
87 | * @param image The image to store
88 | * @param key The unique image cache key, usually it's image absolute URL
89 | * @param toDisk Store the image to disk cache if YES
90 | */
91 | - (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk;
92 |
93 | /**
94 | * Store an image into memory and optionally disk cache at the given key.
95 | *
96 | * @param image The image to store
97 | * @param recalculate BOOL indicates if imageData can be used or a new data should be constructed from the UIImage
98 | * @param imageData The image data as returned by the server, this representation will be used for disk storage
99 | * instead of converting the given image object into a storable/compressed image format in order
100 | * to save quality and CPU
101 | * @param key The unique image cache key, usually it's image absolute URL
102 | * @param toDisk Store the image to disk cache if YES
103 | */
104 | - (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk;
105 |
106 | /**
107 | * Query the disk cache asynchronously.
108 | *
109 | * @param key The unique key used to store the wanted image
110 | */
111 | - (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock;
112 |
113 | /**
114 | * Query the memory cache synchronously.
115 | *
116 | * @param key The unique key used to store the wanted image
117 | */
118 | - (UIImage *)imageFromMemoryCacheForKey:(NSString *)key;
119 |
120 | /**
121 | * Query the disk cache synchronously after checking the memory cache.
122 | *
123 | * @param key The unique key used to store the wanted image
124 | */
125 | - (UIImage *)imageFromDiskCacheForKey:(NSString *)key;
126 |
127 | /**
128 | * Remove the image from memory and disk cache synchronously
129 | *
130 | * @param key The unique image cache key
131 | */
132 | - (void)removeImageForKey:(NSString *)key;
133 |
134 |
135 | /**
136 | * Remove the image from memory and disk cache synchronously
137 | *
138 | * @param key The unique image cache key
139 | * @param completion An block that should be executed after the image has been removed (optional)
140 | */
141 | - (void)removeImageForKey:(NSString *)key withCompletion:(SDWebImageNoParamsBlock)completion;
142 |
143 | /**
144 | * Remove the image from memory and optionally disk cache synchronously
145 | *
146 | * @param key The unique image cache key
147 | * @param fromDisk Also remove cache entry from disk if YES
148 | */
149 | - (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk;
150 |
151 | /**
152 | * Remove the image from memory and optionally disk cache synchronously
153 | *
154 | * @param key The unique image cache key
155 | * @param fromDisk Also remove cache entry from disk if YES
156 | * @param completion An block that should be executed after the image has been removed (optional)
157 | */
158 | - (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(SDWebImageNoParamsBlock)completion;
159 |
160 | /**
161 | * Clear all memory cached images
162 | */
163 | - (void)clearMemory;
164 |
165 | /**
166 | * Clear all disk cached images. Non-blocking method - returns immediately.
167 | * @param completion An block that should be executed after cache expiration completes (optional)
168 | */
169 | - (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion;
170 |
171 | /**
172 | * Clear all disk cached images
173 | * @see clearDiskOnCompletion:
174 | */
175 | - (void)clearDisk;
176 |
177 | /**
178 | * Remove all expired cached image from disk. Non-blocking method - returns immediately.
179 | * @param completionBlock An block that should be executed after cache expiration completes (optional)
180 | */
181 | - (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock;
182 |
183 | /**
184 | * Remove all expired cached image from disk
185 | * @see cleanDiskWithCompletionBlock:
186 | */
187 | - (void)cleanDisk;
188 |
189 | /**
190 | * Get the size used by the disk cache
191 | */
192 | - (NSUInteger)getSize;
193 |
194 | /**
195 | * Get the number of images in the disk cache
196 | */
197 | - (NSUInteger)getDiskCount;
198 |
199 | /**
200 | * Asynchronously calculate the disk cache's size.
201 | */
202 | - (void)calculateSizeWithCompletionBlock:(SDWebImageCalculateSizeBlock)completionBlock;
203 |
204 | /**
205 | * Async check if image exists in disk cache already (does not load the image)
206 | *
207 | * @param key the key describing the url
208 | * @param completionBlock the block to be executed when the check is done.
209 | * @note the completion block will be always executed on the main queue
210 | */
211 | - (void)diskImageExistsWithKey:(NSString *)key completion:(SDWebImageCheckCacheCompletionBlock)completionBlock;
212 |
213 | /**
214 | * Check if image exists in disk cache already (does not load the image)
215 | *
216 | * @param key the key describing the url
217 | *
218 | * @return YES if an image exists for the given key
219 | */
220 | - (BOOL)diskImageExistsWithKey:(NSString *)key;
221 |
222 | /**
223 | * Get the cache path for a certain key (needs the cache path root folder)
224 | *
225 | * @param key the key (can be obtained from url using cacheKeyForURL)
226 | * @param path the cach path root folder
227 | *
228 | * @return the cache path
229 | */
230 | - (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path;
231 |
232 | /**
233 | * Get the default cache path for a certain key
234 | *
235 | * @param key the key (can be obtained from url using cacheKeyForURL)
236 | *
237 | * @return the default cache path
238 | */
239 | - (NSString *)defaultCachePathForKey:(NSString *)key;
240 |
241 | @end
242 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 | #define dispatch_main_sync_safe(block)\
59 | if ([NSThread isMainThread]) {\
60 | block();\
61 | } else {\
62 | dispatch_sync(dispatch_get_main_queue(), block);\
63 | }
64 |
65 | #define dispatch_main_async_safe(block)\
66 | if ([NSThread isMainThread]) {\
67 | block();\
68 | } else {\
69 | dispatch_async(dispatch_get_main_queue(), block);\
70 | }
71 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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. at the end of the string, before a 3 to 4 extension length (only if key len is 8 or more @2x. + 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 |
40 | UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
41 | image = scaledImage;
42 | }
43 | return image;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/SDWebImage/SDWebImageDownloader.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 "SDWebImageOperation.h"
12 |
13 | typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) {
14 | SDWebImageDownloaderLowPriority = 1 << 0,
15 | SDWebImageDownloaderProgressiveDownload = 1 << 1,
16 |
17 | /**
18 | * By default, request prevent the of NSURLCache. With this flag, NSURLCache
19 | * is used with default policies.
20 | */
21 | SDWebImageDownloaderUseNSURLCache = 1 << 2,
22 |
23 | /**
24 | * Call completion block with nil image/imageData if the image was read from NSURLCache
25 | * (to be combined with `SDWebImageDownloaderUseNSURLCache`).
26 | */
27 |
28 | SDWebImageDownloaderIgnoreCachedResponse = 1 << 3,
29 | /**
30 | * In iOS 4+, continue the download of the image if the app goes to background. This is achieved by asking the system for
31 | * extra time in background to let the request finish. If the background task expires the operation will be cancelled.
32 | */
33 |
34 | SDWebImageDownloaderContinueInBackground = 1 << 4,
35 |
36 | /**
37 | * Handles cookies stored in NSHTTPCookieStore by setting
38 | * NSMutableURLRequest.HTTPShouldHandleCookies = YES;
39 | */
40 | SDWebImageDownloaderHandleCookies = 1 << 5,
41 |
42 | /**
43 | * Enable to allow untrusted SSL ceriticates.
44 | * Useful for testing purposes. Use with caution in production.
45 | */
46 | SDWebImageDownloaderAllowInvalidSSLCertificates = 1 << 6,
47 |
48 | /**
49 | * Put the image in the high priority queue.
50 | */
51 | SDWebImageDownloaderHighPriority = 1 << 7,
52 |
53 |
54 | };
55 |
56 | typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) {
57 | /**
58 | * Default value. All download operations will execute in queue style (first-in-first-out).
59 | */
60 | SDWebImageDownloaderFIFOExecutionOrder,
61 |
62 | /**
63 | * All download operations will execute in stack style (last-in-first-out).
64 | */
65 | SDWebImageDownloaderLIFOExecutionOrder
66 | };
67 |
68 | extern NSString *const SDWebImageDownloadStartNotification;
69 | extern NSString *const SDWebImageDownloadStopNotification;
70 |
71 | typedef void(^SDWebImageDownloaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize);
72 |
73 | typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage *image, NSData *data, NSError *error, BOOL finished);
74 |
75 | typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDictionary *headers);
76 |
77 | /**
78 | * Asynchronous downloader dedicated and optimized for image loading.
79 | */
80 | @interface SDWebImageDownloader : NSObject
81 |
82 | @property (assign, nonatomic) NSInteger maxConcurrentDownloads;
83 |
84 | /**
85 | * Shows the current amount of downloads that still need to be downloaded
86 | */
87 |
88 | @property (readonly, nonatomic) NSUInteger currentDownloadCount;
89 |
90 |
91 | /**
92 | * The timeout value (in seconds) for the download operation. Default: 15.0.
93 | */
94 | @property (assign, nonatomic) NSTimeInterval downloadTimeout;
95 |
96 |
97 | /**
98 | * Changes download operations execution order. Default value is `SDWebImageDownloaderFIFOExecutionOrder`.
99 | */
100 | @property (assign, nonatomic) SDWebImageDownloaderExecutionOrder executionOrder;
101 |
102 | /**
103 | * Singleton method, returns the shared instance
104 | *
105 | * @return global shared instance of downloader class
106 | */
107 | + (SDWebImageDownloader *)sharedDownloader;
108 |
109 | /**
110 | * Set username
111 | */
112 | @property (strong, nonatomic) NSString *username;
113 |
114 | /**
115 | * Set password
116 | */
117 | @property (strong, nonatomic) NSString *password;
118 |
119 | /**
120 | * Set filter to pick headers for downloading image HTTP request.
121 | *
122 | * This block will be invoked for each downloading image request, returned
123 | * NSDictionary will be used as headers in corresponding HTTP request.
124 | */
125 | @property (nonatomic, copy) SDWebImageDownloaderHeadersFilterBlock headersFilter;
126 |
127 | /**
128 | * Set a value for a HTTP header to be appended to each download HTTP request.
129 | *
130 | * @param value The value for the header field. Use `nil` value to remove the header.
131 | * @param field The name of the header field to set.
132 | */
133 | - (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;
134 |
135 | /**
136 | * Returns the value of the specified HTTP header field.
137 | *
138 | * @return The value associated with the header field field, or `nil` if there is no corresponding header field.
139 | */
140 | - (NSString *)valueForHTTPHeaderField:(NSString *)field;
141 |
142 | /**
143 | * Sets a subclass of `SDWebImageDownloaderOperation` as the default
144 | * `NSOperation` to be used each time SDWebImage constructs a request
145 | * operation to download an image.
146 | *
147 | * @param operationClass The subclass of `SDWebImageDownloaderOperation` to set
148 | * as default. Passing `nil` will revert to `SDWebImageDownloaderOperation`.
149 | */
150 | - (void)setOperationClass:(Class)operationClass;
151 |
152 | /**
153 | * Creates a SDWebImageDownloader async downloader instance with a given URL
154 | *
155 | * The delegate will be informed when the image is finish downloaded or an error has happen.
156 | *
157 | * @see SDWebImageDownloaderDelegate
158 | *
159 | * @param url The URL to the image to download
160 | * @param options The options to be used for this download
161 | * @param progressBlock A block called repeatedly while the image is downloading
162 | * @param completedBlock A block called once the download is completed.
163 | * If the download succeeded, the image parameter is set, in case of error,
164 | * error parameter is set with the error. The last parameter is always YES
165 | * if SDWebImageDownloaderProgressiveDownload isn't use. With the
166 | * SDWebImageDownloaderProgressiveDownload option, this block is called
167 | * repeatedly with the partial image object and the finished argument set to NO
168 | * before to be called a last time with the full image and finished argument
169 | * set to YES. In case of error, the finished argument is always YES.
170 | *
171 | * @return A cancellable SDWebImageOperation
172 | */
173 | - (id )downloadImageWithURL:(NSURL *)url
174 | options:(SDWebImageDownloaderOptions)options
175 | progress:(SDWebImageDownloaderProgressBlock)progressBlock
176 | completed:(SDWebImageDownloaderCompletedBlock)completedBlock;
177 |
178 | /**
179 | * Sets the download queue suspension state
180 | */
181 | - (void)setSuspended:(BOOL)suspended;
182 |
183 | @end
184 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 | @interface SDWebImageDownloaderOperation : NSOperation
14 |
15 | /**
16 | * The request used by the operation's connection.
17 | */
18 | @property (strong, nonatomic, readonly) NSURLRequest *request;
19 |
20 | /**
21 | * Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default.
22 | *
23 | * This is the value that is returned in the `NSURLConnectionDelegate` method `-connectionShouldUseCredentialStorage:`.
24 | */
25 | @property (nonatomic, assign) BOOL shouldUseCredentialStorage;
26 |
27 | /**
28 | * The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`.
29 | *
30 | * This will be overridden by any shared credentials that exist for the username or password of the request URL, if present.
31 | */
32 | @property (nonatomic, strong) NSURLCredential *credential;
33 |
34 | /**
35 | * The SDWebImageDownloaderOptions for the receiver.
36 | */
37 | @property (assign, nonatomic, readonly) SDWebImageDownloaderOptions options;
38 |
39 | /**
40 | * Initializes a `SDWebImageDownloaderOperation` object
41 | *
42 | * @see SDWebImageDownloaderOperation
43 | *
44 | * @param request the URL request
45 | * @param options downloader options
46 | * @param progressBlock the block executed when a new chunk of data arrives.
47 | * @note the progress block is executed on a background queue
48 | * @param completedBlock the block executed when the download is done.
49 | * @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
50 | * @param cancelBlock the block executed if the download (operation) is cancelled
51 | *
52 | * @return the initialized instance
53 | */
54 | - (id)initWithRequest:(NSURLRequest *)request
55 | options:(SDWebImageDownloaderOptions)options
56 | progress:(SDWebImageDownloaderProgressBlock)progressBlock
57 | completed:(SDWebImageDownloaderCompletedBlock)completedBlock
58 | cancelled:(SDWebImageNoParamsBlock)cancelBlock;
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 | @property (weak, nonatomic) id delegate;
62 |
63 | /**
64 | * Return the global image prefetcher instance.
65 | */
66 | + (SDWebImagePrefetcher *)sharedImagePrefetcher;
67 |
68 | /**
69 | * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching,
70 | * currently one image is downloaded at a time,
71 | * and skips images for failed downloads and proceed to the next image in the list
72 | *
73 | * @param urls list of URLs to prefetch
74 | */
75 | - (void)prefetchURLs:(NSArray *)urls;
76 |
77 | /**
78 | * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching,
79 | * currently one image is downloaded at a time,
80 | * and skips images for failed downloads and proceed to the next image in the list
81 | *
82 | * @param urls list of URLs to prefetch
83 | * @param progressBlock block to be called when progress updates;
84 | * first parameter is the number of completed (successful or not) requests,
85 | * second parameter is the total number of images originally requested to be prefetched
86 | * @param completionBlock block to be called when prefetching is completed
87 | * first param is the number of completed (successful or not) requests,
88 | * second parameter is the number of skipped requests
89 | */
90 | - (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock;
91 |
92 | /**
93 | * Remove and cancel queued list
94 | */
95 | - (void)cancelPrefetching;
96 |
97 |
98 | @end
99 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 | self.maxConcurrentDownloads = 3;
44 | }
45 | return self;
46 | }
47 |
48 | - (void)setMaxConcurrentDownloads:(NSUInteger)maxConcurrentDownloads {
49 | self.manager.imageDownloader.maxConcurrentDownloads = maxConcurrentDownloads;
50 | }
51 |
52 | - (NSUInteger)maxConcurrentDownloads {
53 | return self.manager.imageDownloader.maxConcurrentDownloads;
54 | }
55 |
56 | - (void)startPrefetchingAtIndex:(NSUInteger)index {
57 | if (index >= self.prefetchURLs.count) return;
58 | self.requestedCount++;
59 | [self.manager downloadImageWithURL:self.prefetchURLs[index] options:self.options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
60 | if (!finished) return;
61 | self.finishedCount++;
62 |
63 | if (image) {
64 | if (self.progressBlock) {
65 | self.progressBlock(self.finishedCount,[self.prefetchURLs count]);
66 | }
67 | NSLog(@"Prefetched %@ out of %@", @(self.finishedCount), @(self.prefetchURLs.count));
68 | }
69 | else {
70 | if (self.progressBlock) {
71 | self.progressBlock(self.finishedCount,[self.prefetchURLs count]);
72 | }
73 | NSLog(@"Prefetched %@ out of %@ (Failed)", @(self.finishedCount), @(self.prefetchURLs.count));
74 |
75 | // Add last failed
76 | self.skippedCount++;
77 | }
78 | if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didPrefetchURL:finishedCount:totalCount:)]) {
79 | [self.delegate imagePrefetcher:self
80 | didPrefetchURL:self.prefetchURLs[index]
81 | finishedCount:self.finishedCount
82 | totalCount:self.prefetchURLs.count
83 | ];
84 | }
85 |
86 | if (self.prefetchURLs.count > self.requestedCount) {
87 | dispatch_async(dispatch_get_main_queue(), ^{
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 | }
98 | }];
99 | }
100 |
101 | - (void)reportStatus {
102 | NSUInteger total = [self.prefetchURLs count];
103 | NSLog(@"Finished prefetching (%@ successful, %@ skipped, timeElasped %.2f)", @(total - self.skippedCount), @(self.skippedCount), CFAbsoluteTimeGetCurrent() - self.startedTime);
104 | if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didFinishWithTotalCount:skippedCount:)]) {
105 | [self.delegate imagePrefetcher:self
106 | didFinishWithTotalCount:(total - self.skippedCount)
107 | skippedCount:self.skippedCount
108 | ];
109 | }
110 | }
111 |
112 | - (void)prefetchURLs:(NSArray *)urls {
113 | [self prefetchURLs:urls progress:nil completed:nil];
114 | }
115 |
116 | - (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock {
117 | [self cancelPrefetching]; // Prevent duplicate prefetch request
118 | self.startedTime = CFAbsoluteTimeGetCurrent();
119 | self.prefetchURLs = urls;
120 | self.completionBlock = completionBlock;
121 | self.progressBlock = progressBlock;
122 |
123 | if(urls.count == 0){
124 | if(completionBlock){
125 | completionBlock(0,0);
126 | }
127 | }else{
128 | // Starts prefetching from the very first image on the list with the max allowed concurrency
129 | NSUInteger listCount = self.prefetchURLs.count;
130 | for (NSUInteger i = 0; i < self.maxConcurrentDownloads && self.requestedCount < listCount; i++) {
131 | [self startPrefetchingAtIndex:i];
132 | }
133 | }
134 | }
135 |
136 | - (void)cancelPrefetching {
137 | self.prefetchURLs = nil;
138 | self.skippedCount = 0;
139 | self.requestedCount = 0;
140 | self.finishedCount = 0;
141 | [self.manager cancelAll];
142 | }
143 |
144 | @end
145 |
--------------------------------------------------------------------------------
/ZZPhotoKit/SDWebImage/UIButton+WebCache.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 "UIButton+WebCache.h"
10 | #import "objc/runtime.h"
11 | #import "UIView+WebCacheOperation.h"
12 |
13 | static char imageURLStorageKey;
14 |
15 | @implementation UIButton (WebCache)
16 |
17 | - (NSURL *)sd_currentImageURL {
18 | NSURL *url = self.imageURLStorage[@(self.state)];
19 |
20 | if (!url) {
21 | url = self.imageURLStorage[@(UIControlStateNormal)];
22 | }
23 |
24 | return url;
25 | }
26 |
27 | - (NSURL *)sd_imageURLForState:(UIControlState)state {
28 | return self.imageURLStorage[@(state)];
29 | }
30 |
31 | - (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state {
32 | [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];
33 | }
34 |
35 | - (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder {
36 | [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil];
37 | }
38 |
39 | - (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
40 | [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil];
41 | }
42 |
43 | - (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock {
44 | [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock];
45 | }
46 |
47 | - (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock {
48 | [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock];
49 | }
50 |
51 | - (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
52 |
53 | [self setImage:placeholder forState:state];
54 | [self sd_cancelImageLoadForState:state];
55 |
56 | if (!url) {
57 | [self.imageURLStorage removeObjectForKey:@(state)];
58 |
59 | dispatch_main_async_safe(^{
60 | NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
61 | if (completedBlock) {
62 | completedBlock(nil, error, SDImageCacheTypeNone, url);
63 | }
64 | });
65 |
66 | return;
67 | }
68 |
69 | self.imageURLStorage[@(state)] = url;
70 |
71 | __weak UIButton *wself = self;
72 | id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
73 | if (!wself) return;
74 | dispatch_main_sync_safe(^{
75 | __strong UIButton *sself = wself;
76 | if (!sself) return;
77 | if (image) {
78 | [sself setImage:image forState:state];
79 | }
80 | if (completedBlock && finished) {
81 | completedBlock(image, error, cacheType, url);
82 | }
83 | });
84 | }];
85 | [self sd_setImageLoadOperation:operation forState:state];
86 | }
87 |
88 | - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state {
89 | [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];
90 | }
91 |
92 | - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder {
93 | [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil];
94 | }
95 |
96 | - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
97 | [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil];
98 | }
99 |
100 | - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock {
101 | [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock];
102 | }
103 |
104 | - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock {
105 | [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock];
106 | }
107 |
108 | - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
109 | [self sd_cancelImageLoadForState:state];
110 |
111 | [self setBackgroundImage:placeholder forState:state];
112 |
113 | if (url) {
114 | __weak UIButton *wself = self;
115 | id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
116 | if (!wself) return;
117 | dispatch_main_sync_safe(^{
118 | __strong UIButton *sself = wself;
119 | if (!sself) return;
120 | if (image) {
121 | [sself setBackgroundImage:image forState:state];
122 | }
123 | if (completedBlock && finished) {
124 | completedBlock(image, error, cacheType, url);
125 | }
126 | });
127 | }];
128 | [self sd_setBackgroundImageLoadOperation:operation forState:state];
129 | } else {
130 | dispatch_main_async_safe(^{
131 | NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
132 | if (completedBlock) {
133 | completedBlock(nil, error, SDImageCacheTypeNone, url);
134 | }
135 | });
136 | }
137 | }
138 |
139 | - (void)sd_setImageLoadOperation:(id)operation forState:(UIControlState)state {
140 | [self sd_setImageLoadOperation:operation forKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]];
141 | }
142 |
143 | - (void)sd_cancelImageLoadForState:(UIControlState)state {
144 | [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]];
145 | }
146 |
147 | - (void)sd_setBackgroundImageLoadOperation:(id)operation forState:(UIControlState)state {
148 | [self sd_setImageLoadOperation:operation forKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]];
149 | }
150 |
151 | - (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state {
152 | [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]];
153 | }
154 |
155 | - (NSMutableDictionary *)imageURLStorage {
156 | NSMutableDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey);
157 | if (!storage)
158 | {
159 | storage = [NSMutableDictionary dictionary];
160 | objc_setAssociatedObject(self, &imageURLStorageKey, storage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
161 | }
162 |
163 | return storage;
164 | }
165 |
166 | @end
167 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 UIImageView *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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/SDWebImage/UIImageView+WebCache.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+WebCache.h"
10 | #import "objc/runtime.h"
11 | #import "UIView+WebCacheOperation.h"
12 |
13 | static char imageURLKey;
14 |
15 | @implementation UIImageView (WebCache)
16 |
17 | - (void)sd_setImageWithURL:(NSURL *)url {
18 | [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
19 | }
20 |
21 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
22 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];
23 | }
24 |
25 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
26 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];
27 | }
28 |
29 | - (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock {
30 | [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];
31 | }
32 |
33 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock {
34 | [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock];
35 | }
36 |
37 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
38 | [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock];
39 | }
40 |
41 | - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
42 | [self sd_cancelCurrentImageLoad];
43 | objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
44 |
45 | if (!(options & SDWebImageDelayPlaceholder)) {
46 | dispatch_main_async_safe(^{
47 | self.image = placeholder;
48 | });
49 | }
50 |
51 | if (url) {
52 | __weak UIImageView *wself = self;
53 | id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
54 | if (!wself) return;
55 | dispatch_main_sync_safe(^{
56 | if (!wself) return;
57 | if (image) {
58 | wself.image = image;
59 | [wself setNeedsLayout];
60 | } else {
61 | if ((options & SDWebImageDelayPlaceholder)) {
62 | wself.image = placeholder;
63 | [wself setNeedsLayout];
64 | }
65 | }
66 | if (completedBlock && finished) {
67 | completedBlock(image, error, cacheType, url);
68 | }
69 | });
70 | }];
71 | [self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
72 | } else {
73 | dispatch_main_async_safe(^{
74 | NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
75 | if (completedBlock) {
76 | completedBlock(nil, error, SDImageCacheTypeNone, url);
77 | }
78 | });
79 | }
80 | }
81 |
82 | - (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
83 | NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url];
84 | UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key];
85 |
86 | [self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock];
87 | }
88 |
89 | - (NSURL *)sd_imageURL {
90 | return objc_getAssociatedObject(self, &imageURLKey);
91 | }
92 |
93 | - (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs {
94 | [self sd_cancelCurrentAnimationImagesLoad];
95 | __weak UIImageView *wself = self;
96 |
97 | NSMutableArray *operationsArray = [[NSMutableArray alloc] init];
98 |
99 | for (NSURL *logoImageURL in arrayOfURLs) {
100 | id operation = [SDWebImageManager.sharedManager downloadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
101 | if (!wself) return;
102 | dispatch_main_sync_safe(^{
103 | __strong UIImageView *sself = wself;
104 | [sself stopAnimating];
105 | if (sself && image) {
106 | NSMutableArray *currentImages = [[sself animationImages] mutableCopy];
107 | if (!currentImages) {
108 | currentImages = [[NSMutableArray alloc] init];
109 | }
110 | [currentImages addObject:image];
111 |
112 | sself.animationImages = currentImages;
113 | [sself setNeedsLayout];
114 | }
115 | [sself startAnimating];
116 | });
117 | }];
118 | [operationsArray addObject:operation];
119 | }
120 |
121 | [self sd_setImageLoadOperation:[NSArray arrayWithArray:operationsArray] forKey:@"UIImageViewAnimationImages"];
122 | }
123 |
124 | - (void)sd_cancelCurrentImageLoad {
125 | [self sd_cancelImageLoadOperationWithKey:@"UIImageViewImageLoad"];
126 | }
127 |
128 | - (void)sd_cancelCurrentAnimationImagesLoad {
129 | [self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"];
130 | }
131 |
132 | @end
133 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/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 |
--------------------------------------------------------------------------------
/ZZPhotoKit/SVProgressHUD/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/SVProgressHUD/.DS_Store
--------------------------------------------------------------------------------
/ZZPhotoKit/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // ZZPhotoKit
4 | //
5 | // Created by Yuan on 16/1/4.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 | @end
14 |
15 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // ZZPhotoKit
4 | //
5 | // Created by Yuan on 16/1/4.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "ZZPhotoKit.h"
11 | #import "PicsCell.h"
12 |
13 | #
14 |
15 | @interface ViewController ()
16 |
17 | @property(strong,nonatomic) UILabel *firstlab;
18 | @property(strong,nonatomic) UIImageView *imageView;
19 | @property(strong,nonatomic) UITableView *tableView;
20 | @property(strong,nonatomic) NSArray *array;
21 |
22 | @property(strong,nonatomic) UICollectionView *collectionView;
23 | @property(strong,nonatomic) UIButton *addBtn;
24 | @property(copy ,nonatomic) NSArray *picArray;
25 |
26 | @end
27 |
28 | @implementation ViewController
29 | -(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
30 | {
31 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
32 | if (self) {
33 | self.navigationItem.title = @"ZZPhotoKit";
34 | }
35 | return self;
36 | }
37 |
38 |
39 | -(UIButton *)addBtn
40 | {
41 | if (!_addBtn) {
42 | CGFloat photoSize = ([UIScreen mainScreen].bounds.size.width - 30) / 4;
43 | _addBtn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, photoSize, photoSize)];
44 | [_addBtn setImage:[UIImage imageNamed:@"photo_add.png"] forState:UIControlStateNormal];
45 | [_addBtn addTarget:self action:@selector(addPhotoMethod) forControlEvents:UIControlEventTouchUpInside];
46 | }
47 | return _addBtn;
48 | }
49 |
50 |
51 |
52 | - (void)viewDidLoad {
53 | [super viewDidLoad];
54 |
55 | self.edgesForExtendedLayout = UIRectEdgeNone;
56 | _array = @[@"相册选择",@"相机"];
57 |
58 | _tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, ZZ_VW, 100)];
59 | _tableView.dataSource = self;
60 | _tableView.delegate = self;
61 | _tableView.scrollEnabled = NO;
62 |
63 | [self.view addSubview:_tableView];
64 |
65 |
66 | UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc]init];
67 |
68 | CGFloat photoSize = (self.view.frame.size.width - 50) / 3;
69 | flowLayout.minimumInteritemSpacing = 10.0;//item 之间的行的距离
70 | flowLayout.minimumLineSpacing = 10.0;//item 之间竖的距离
71 | flowLayout.itemSize = (CGSize){photoSize,photoSize};
72 | // self.sectionInset = UIEdgeInsetsMake(0, 2, 0, 0);
73 | flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
74 |
75 | _collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(10, 170, ZZ_VW - 20, photoSize * 3) collectionViewLayout:flowLayout];
76 | [_collectionView registerClass:[PicsCell class] forCellWithReuseIdentifier:@"PhotoCell"];
77 | _collectionView.delegate = self;
78 | _collectionView.dataSource = self;
79 | _collectionView.backgroundColor = [UIColor whiteColor];
80 | [_collectionView setUserInteractionEnabled:YES];
81 | [self.view addSubview:_collectionView];
82 |
83 | }
84 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
85 | {
86 | return 1;
87 | }
88 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
89 | {
90 | return _array.count;
91 | }
92 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
93 | {
94 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
95 | cell.backgroundColor = [UIColor redColor];
96 | if (!cell) {
97 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
98 | }
99 | cell.textLabel.text = [_array objectAtIndex:indexPath.row];
100 | return cell;
101 | }
102 | -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
103 | {
104 | return 50;
105 | }
106 |
107 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
108 | {
109 | if (indexPath.row == 0) {
110 |
111 |
112 |
113 | ZZPhotoController *photoController = [[ZZPhotoController alloc]init];
114 | photoController.selectPhotoOfMax = 8;
115 | //设置相册中完成按钮旁边小圆点颜色。
116 | // photoController.roundColor = [UIColor greenColor];
117 |
118 | [photoController showIn:self result:^(id responseObject){
119 |
120 |
121 | self.picArray = (NSArray *)responseObject;
122 | // NSLog(@"重载");
123 | [_collectionView reloadData];
124 |
125 | }];
126 |
127 |
128 | }else if(indexPath.row == 1){
129 | ZZCameraController *cameraController = [[ZZCameraController alloc]init];
130 | cameraController.takePhotoOfMax = 8;
131 |
132 | cameraController.isSaveLocal = NO;
133 | [cameraController showIn:self result:^(id responseObject){
134 |
135 | NSLog(@"%@",responseObject);
136 |
137 | self.picArray = (NSArray *)responseObject;
138 | [_collectionView reloadData];
139 | }];
140 | }
141 | }
142 |
143 |
144 |
145 | #pragma mark --- ZZBrowserPickerDelegate
146 | -(NSInteger)zzbrowserPickerPhotoNum:(ZZBrowserPickerViewController *)controller
147 | {
148 | return 5;
149 | }
150 |
151 | -(NSArray *)zzbrowserPickerPhotoContent:(ZZBrowserPickerViewController *)controller
152 | {
153 | NSArray *array = @[
154 | @"http://pic86.nipic.com/file/20151229/11592367_090842563000_2.jpg",
155 | [UIImage imageNamed:@"scv2.jpg"],
156 | [UIImage imageNamed:@"scv3.jpg"],
157 | [UIImage imageNamed:@"scv4.jpg"],
158 | [UIImage imageNamed:@"scv5.jpg"],
159 | ];
160 | return array;
161 | }
162 |
163 |
164 | -(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
165 | {
166 |
167 | return 1;
168 | }
169 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
170 | {
171 | return self.picArray.count;
172 | }
173 |
174 | -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
175 | {
176 | PicsCell *photoCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"PhotoCell" forIndexPath:indexPath];
177 | if (!photoCell) {
178 | photoCell = [[PicsCell alloc]init];
179 | }
180 | if ([[self.picArray objectAtIndex:indexPath.row] isKindOfClass:[ZZPhoto class]]) {
181 |
182 | //从数组里面把model取出来
183 | ZZPhoto *photo = [self.picArray objectAtIndex:indexPath.row];
184 |
185 | //用photo对象中的originImage属性来展示图片
186 | photoCell.photo.image = photo.originImage;
187 |
188 |
189 | }else if([[self.picArray objectAtIndex:indexPath.row] isKindOfClass:[ZZCamera class]]){
190 |
191 | ZZCamera *camera = [self.picArray objectAtIndex:indexPath.row];
192 | photoCell.photo.image = camera.image;
193 |
194 | }
195 |
196 |
197 | return photoCell;
198 | }
199 |
200 | - (void)didReceiveMemoryWarning {
201 | [super didReceiveMemoryWarning];
202 | // Dispose of any resources that can be recreated.
203 | }
204 |
205 | @end
206 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Other/ZZAlumAnimation.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZAlumAnimation.h
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/19.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 | @interface ZZAlumAnimation : NSObject
12 |
13 | +(ZZAlumAnimation *)sharedAnimation;
14 |
15 | -(void) roundAnimation:(UILabel *)label;
16 |
17 | -(void) selectAnimation:(UIButton *)button;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Other/ZZAlumAnimation.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZAlumAnimation.m
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/19.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "ZZAlumAnimation.h"
10 |
11 | @implementation ZZAlumAnimation
12 |
13 | +(ZZAlumAnimation *)sharedAnimation
14 | {
15 | static ZZAlumAnimation *animation = nil;
16 | if (animation == nil) {
17 | animation = [[ZZAlumAnimation alloc]init];
18 | }
19 | return animation;
20 | }
21 |
22 | -(void)roundAnimation:(UILabel *)label
23 | {
24 | CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
25 | animation.duration = 0.7;
26 |
27 | NSMutableArray *values = [NSMutableArray array];
28 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)]];
29 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.2, 1.2, 1.0)]];
30 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9, 0.9, 1.0)]];
31 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1.0)]];
32 | animation.values = values;
33 | [label.layer addAnimation:animation forKey:nil];
34 | }
35 |
36 | -(void)selectAnimation:(UIButton *)button
37 | {
38 | CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
39 | animation.duration = 0.5;
40 |
41 | NSMutableArray *values = [NSMutableArray array];
42 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)]];
43 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.2, 1.2, 1.0)]];
44 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9, 0.9, 1.0)]];
45 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1.0)]];
46 | animation.values = values;
47 | [button.layer addAnimation:animation forKey:nil];
48 | }
49 |
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/back_button_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/back_button_normal.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/back_button_normal@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/back_button_normal@2x.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/camera_focus_pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/camera_focus_pic.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/change_camera_pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/change_camera_pic.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/flash_close_pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/flash_close_pic.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/flash_open_pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/flash_open_pic.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/no_data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/no_data.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/photo_add.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/photo_add.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/remove_btn_pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/remove_btn_pic.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/select_no.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/select_no.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/select_yes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/select_yes.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/take_photo_pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/take_photo_pic.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/take_photo_pic@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/take_photo_pic@2x.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/trash_btn_pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/trash_btn_pic.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/Resources/zz_alumb_rightCell.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/ZZPhotoKit/ZZPhotoKit/Public/Resources/zz_alumb_rightCell.png
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/Public/ZZResourceConfig.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZResourceConfig.h
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/19.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #ifndef ZZResourceConfig_h
10 | #define ZZResourceConfig_h
11 | /////配置文件/////
12 |
13 |
14 | /*
15 | 公共文件
16 | */
17 | #import
18 | #import
19 | #import
20 | #import
21 | #import "UIImageView+WebCache.h"
22 |
23 | #import
24 | #import
25 | #import
26 | #import
27 |
28 |
29 | /*
30 | 控制器
31 | */
32 | #define ZZ_VW (self.view.frame.size.width)
33 | #define ZZ_VH (self.view.frame.size.height)
34 |
35 | #define ZZ_SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
36 | #define ZZ_SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
37 |
38 | /*
39 | 颜色
40 | */
41 | #define ZZ_RGBA(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
42 | #define ZZ_RGB(r,g,b) ZZ_RGBA(r,g,b,1.0f)
43 |
44 | /*
45 | 图片
46 | */
47 |
48 | // 相册列表页面右边箭头图片
49 | #define PhotoListRightBtn [UIImage imageNamed:@"zz_alumb_rightCell.png"]
50 | // 相册列表页面,当没有数据时使用图片
51 | #define NOPhoto_Data_Pic [UIImage imageNamed:@"no_data.png"]
52 | // 图片选中状态图片
53 | #define Pic_Btn_Selected [UIImage imageNamed:@"select_yes.png"]
54 | // 图片未选中状态图片
55 | #define Pic_btn_UnSelected [UIImage imageNamed:@"select_no.png"]
56 | // 拍照图片
57 | #define TakePhoto_Btn_Pic [UIImage imageNamed:@"take_photo_pic.png"]
58 | // 闪光灯按钮图片
59 | #define Flash_Open_Btn_Pic [UIImage imageNamed:@"flash_open_pic.png"]
60 | #define Flash_close_Btn_Pic [UIImage imageNamed:@"flash_close_pic.png"]
61 | // 切换前置后置摄像头按钮
62 | #define Change_Btn_Pic [UIImage imageNamed:@"change_camera_pic.png"]
63 | // 删除图片按钮
64 | #define Remove_Btn_Pic [UIImage imageNamed:@"remove_btn_pic.png"]
65 |
66 | /*
67 | 文字
68 | */
69 | // 相册详细页面底部Footer显示文字
70 | #define Total_Photo_Num @"%lu 张照片"
71 | #define Total_Video_Num @"%lu 个视频"
72 | #define Alert_Max_Selected @"最多只能选择%lu张图片"
73 | #define Alert_Max_TakePhoto @"最多连拍张数为%lu张图片"
74 |
75 |
76 | #endif /* ZZResourceConfig_h */
77 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZBrowser/ZZBrowserPickerCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZBrowserPickerCell.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/23.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 |
12 | @protocol ZZBrowserPickerCellDelegate
13 |
14 | -(void) clickZoomView;
15 |
16 | @end
17 |
18 | @interface ZZBrowserPickerCell : UICollectionViewCell
19 |
20 | @property (nonatomic, strong) UIImageView *pics;
21 |
22 | @property (nonatomic, weak) iddelegate;
23 |
24 | -(void)loadPHAssetItemForPics:(PHAsset *)assetItem;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZBrowser/ZZBrowserPickerCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZBrowserPickerCell.m
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/23.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import "ZZBrowserPickerCell.h"
10 |
11 | @interface ZZBrowserPickerCell()
12 | {
13 | CGFloat _browser_width;
14 | CGFloat _browser_height;
15 | }
16 | @property (nonatomic, strong) UIScrollView *scaleView;
17 |
18 | @end
19 |
20 | @implementation ZZBrowserPickerCell
21 |
22 | -(instancetype)initWithFrame:(CGRect)frame
23 | {
24 | self = [super initWithFrame:frame];
25 | if (self) {
26 |
27 | _browser_width = frame.size.width;
28 | _browser_height = frame.size.height;
29 |
30 | _scaleView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, _browser_width, _browser_height)];
31 | _scaleView.delegate = self;
32 | _scaleView.maximumZoomScale = 2.5;
33 | _scaleView.minimumZoomScale = 1.0;
34 | _scaleView.bouncesZoom = YES;
35 | _scaleView.multipleTouchEnabled = YES;
36 | _scaleView.delegate = self;
37 | _scaleView.scrollsToTop = NO;
38 | _scaleView.showsHorizontalScrollIndicator = NO;
39 | _scaleView.showsVerticalScrollIndicator = NO;
40 | _scaleView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
41 | _scaleView.delaysContentTouches = NO;
42 | _scaleView.canCancelContentTouches = YES;
43 | _scaleView.alwaysBounceVertical = NO;
44 | _scaleView.userInteractionEnabled = YES;
45 | [self.contentView addSubview:_scaleView];
46 |
47 |
48 | _pics = [[UIImageView alloc]init];
49 | _pics.contentMode = UIViewContentModeScaleAspectFit;
50 | [_scaleView addSubview:_pics];
51 |
52 |
53 | UITapGestureRecognizer *tapScaleFingerOne = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleFingerEvent:)];
54 | tapScaleFingerOne.delegate = self;
55 | tapScaleFingerOne.numberOfTapsRequired = 1;
56 | [_scaleView addGestureRecognizer:tapScaleFingerOne];
57 |
58 | UITapGestureRecognizer *singleFingerOne = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleFingerEvent:)];
59 | singleFingerOne.delegate = self;
60 | singleFingerOne.numberOfTapsRequired = 1;
61 | [_pics addGestureRecognizer:singleFingerOne];
62 |
63 |
64 | UITapGestureRecognizer *singleFingerTwo = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleFingerEvent:)];
65 | singleFingerTwo.delegate = self;
66 | singleFingerTwo.numberOfTapsRequired = 2;
67 | [_pics addGestureRecognizer:singleFingerTwo];
68 |
69 | }
70 | return self;
71 | }
72 |
73 | -(void)loadPHAssetItemForPics:(PHAsset *)assetItem
74 | {
75 | PHAsset *phAsset = (PHAsset *)assetItem;
76 |
77 | CGFloat photoWidth = [UIScreen mainScreen].bounds.size.width;
78 |
79 | CGFloat aspectRatio = phAsset.pixelWidth / (CGFloat)phAsset.pixelHeight;
80 | CGFloat multiple = [UIScreen mainScreen].scale;
81 | CGFloat pixelWidth = photoWidth * multiple;
82 | CGFloat pixelHeight = pixelWidth / aspectRatio;
83 |
84 | PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
85 | option.resizeMode = PHImageRequestOptionsResizeModeFast;
86 | [[PHImageManager defaultManager] requestImageForAsset:phAsset targetSize:CGSizeMake(pixelWidth, pixelHeight) contentMode:PHImageContentModeAspectFit options:option resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
87 |
88 | BOOL downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
89 |
90 | //设置BOOL判断,确定返回高清照片
91 | if (downloadFinined) {
92 |
93 | if (result != nil) {
94 | [self changeFrameWithImage:result];
95 | self.pics.image = result;
96 | }
97 | }
98 |
99 | }];
100 | }
101 |
102 | -(void)changeFrameWithImage:(UIImage *)image
103 | {
104 | CGFloat height = image.size.height / image.size.width * _browser_width;
105 | self.pics.frame = CGRectMake(0, 0, _browser_width, height);
106 | self.pics.center = CGPointMake(_browser_width / 2, _browser_height / 2);
107 | _scaleView.contentSize = CGSizeMake(_browser_width, MAX(self.pics.frame.size.height, _browser_height));
108 | }
109 |
110 | -(void)setNeedsDisplay
111 | {
112 | [_scaleView setZoomScale:1.0 animated:NO];
113 | }
114 |
115 | -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
116 | {
117 | return _pics;
118 | }
119 |
120 | -(void)scrollViewDidZoom:(UIScrollView *)scrollView
121 | {
122 | CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width)?
123 | (scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
124 | CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height)?
125 | (scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
126 | _pics.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX,
127 | scrollView.contentSize.height * 0.5 + offsetY);
128 | }
129 |
130 | - (void)handleSingleFingerEvent:(UITapGestureRecognizer *)sender
131 | {
132 | if (sender.numberOfTapsRequired == 1) {
133 | if ([self.delegate respondsToSelector:@selector(clickZoomView)]) {
134 | [self.delegate clickZoomView];
135 | }
136 | }else if(sender.numberOfTapsRequired == 2){
137 |
138 |
139 |
140 | }
141 | }
142 |
143 |
144 | @end
145 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZBrowser/ZZBrowserPickerViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZBrowserPickerViewController.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/23.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 |
10 | #import
11 | #import "ZZResourceConfig.h"
12 |
13 | typedef NS_ENUM(NSInteger, ShowAnimation){
14 | ShowAnimationOfPush,
15 | ShowAnimationOfPresent
16 |
17 | };
18 | @class ZZBrowserPickerViewController;
19 |
20 | @protocol ZZBrowserPickerDelegate
21 |
22 | @required
23 | -(NSInteger)zzbrowserPickerPhotoNum:(ZZBrowserPickerViewController *)controller;
24 | -(NSArray *)zzbrowserPickerPhotoContent:(ZZBrowserPickerViewController *)controller;
25 |
26 | @optional
27 | -(void)zzbrowerPickerPhotoRemove:(NSInteger) indexPath;
28 |
29 | @end
30 |
31 | @interface ZZBrowserPickerViewController : UIViewController
32 |
33 | @property (assign, nonatomic) id delegate;
34 |
35 | //是否开启动画效果
36 | @property (assign, nonatomic) BOOL isOpenAnimation;
37 |
38 | @property (assign, nonatomic) NSInteger showAnimation;
39 | //滚动到指定位置(滚动到那张图片,通过下面属性)
40 | @property (strong, nonatomic) NSIndexPath *indexPath;
41 |
42 | -(void)reloadData;
43 |
44 | -(void)showIn:(UIViewController *)controller animation:(ShowAnimation)animation;
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZBrowser/ZZPageControl.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPageControl.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/31.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ZZPageControl : UIView
12 |
13 | @property (assign,nonatomic) NSInteger currentPage;
14 | @property (strong,nonatomic) UILabel *pageControl;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZBrowser/ZZPageControl.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPageControl.m
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/31.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import "ZZPageControl.h"
10 |
11 | @implementation ZZPageControl
12 |
13 | -(instancetype)initWithFrame:(CGRect)frame
14 | {
15 | self = [super initWithFrame:frame];
16 | if (self) {
17 |
18 | _pageControl = [[UILabel alloc]initWithFrame:CGRectMake(5, 3, self.frame.size.width - 10, self.frame.size.height - 6)];
19 | _pageControl.backgroundColor = [UIColor clearColor];
20 | _pageControl.textAlignment = NSTextAlignmentCenter;
21 | [self addSubview:_pageControl];
22 | }
23 | return self;
24 | }
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/Controller/ZZCameraBrowerViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCameraBrowerViewController.h
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/27.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class ZZCameraBrowerViewController;
12 |
13 | @protocol ZZCameraBrowerDataSource
14 |
15 | @required
16 | -(NSInteger)zzbrowserPickerPhotoNum:(ZZCameraBrowerViewController *)controller;
17 | -(NSArray *)zzbrowserPickerPhotoContent:(ZZCameraBrowerViewController *)controller;
18 |
19 | @end
20 |
21 | @interface ZZCameraBrowerViewController : UIViewController
22 |
23 | @property (nonatomic, weak) id delegate;
24 |
25 | //滚动到指定位置(滚动到那张图片,通过下面属性)
26 | @property (nonatomic, strong) NSIndexPath *indexPath;
27 |
28 | -(void)reloadData;
29 |
30 | -(void)showIn:(UIViewController *)controller;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/Controller/ZZCameraBrowerViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCameraBrowerViewController.m
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/27.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "ZZCameraBrowerViewController.h"
10 | #import "ZZCameraBrowerCell.h"
11 | #import "ZZPageControl.h"
12 | #import "ZZCamera.h"
13 |
14 | @interface ZZCameraBrowerViewController ()
15 |
16 | @property (nonatomic, strong) UICollectionView *picBrowse;
17 | @property (nonatomic, strong) NSMutableArray *photoDataArray;
18 | @property (nonatomic, strong) ZZPageControl *pageControl;
19 | @property (nonatomic, assign) NSInteger numberOfItems;
20 |
21 | @end
22 |
23 | @implementation ZZCameraBrowerViewController
24 |
25 |
26 | -(void)setupCollectionViewUI
27 | {
28 | self.edgesForExtendedLayout = UIRectEdgeNone;
29 | /*
30 | * 创建核心内容 UICollectionView
31 | */
32 | self.view.backgroundColor = [UIColor blackColor];
33 |
34 |
35 | UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
36 | flowLayout.itemSize = (CGSize){self.view.frame.size.width,self.view.frame.size.height};
37 | flowLayout.minimumLineSpacing = 0.0f;
38 | flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
39 |
40 | _picBrowse = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:flowLayout];
41 | _picBrowse.backgroundColor = [UIColor clearColor];
42 | _picBrowse.pagingEnabled = YES;
43 |
44 | _picBrowse.showsHorizontalScrollIndicator = NO;
45 | _picBrowse.showsVerticalScrollIndicator = NO;
46 | [_picBrowse registerClass:[ZZCameraBrowerCell class] forCellWithReuseIdentifier:NSStringFromClass([ZZCameraBrowerCell class])];
47 | _picBrowse.dataSource = self;
48 | _picBrowse.delegate = self;
49 | _picBrowse.translatesAutoresizingMaskIntoConstraints = NO;
50 |
51 |
52 | [self.view addSubview:_picBrowse];
53 |
54 | NSLayoutConstraint *list_top = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_picBrowse attribute:NSLayoutAttributeTop multiplier:1 constant:0.0f];
55 |
56 | NSLayoutConstraint *list_bottom = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:_picBrowse attribute:NSLayoutAttributeBottom multiplier:1 constant:0.0f];
57 |
58 | NSLayoutConstraint *list_left = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:_picBrowse attribute:NSLayoutAttributeLeft multiplier:1 constant:0.0f];
59 |
60 | NSLayoutConstraint *list_right = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:_picBrowse attribute:NSLayoutAttributeRight multiplier:1 constant:0.0f];
61 |
62 | [self.view addConstraints:@[list_top,list_bottom,list_left,list_right]];
63 |
64 | }
65 |
66 | -(void)viewDidLayoutSubviews
67 | {
68 | [super viewDidLayoutSubviews];
69 | if (self.indexPath != nil) {
70 | [_picBrowse scrollToItemAtIndexPath:self.indexPath atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
71 | }
72 | }
73 |
74 | -(void)setPageControlUI
75 | {
76 | _pageControl = [[ZZPageControl alloc]initWithFrame:CGRectMake(0, self.view.frame.size.height - 80, self.view.frame.size.width, 30)];
77 | _pageControl.currentPage = 0;
78 | _pageControl.backgroundColor = [UIColor clearColor];
79 | _pageControl.pageControl.textColor = [UIColor whiteColor];
80 | [self.view addSubview:_pageControl];
81 |
82 | //照片总数通过delegate获取
83 | _numberOfItems = [self.delegate zzbrowserPickerPhotoNum:self];
84 |
85 | //判断是否需要滚动到指定图片
86 | if (self.indexPath != nil) {
87 | _pageControl.pageControl.text = [NSString stringWithFormat:@"%ld / %ld",(long)self.indexPath.row + 1,(long)_numberOfItems];
88 | }else{
89 | _pageControl.pageControl.text = [NSString stringWithFormat:@"%d / %ld",1,(long)_numberOfItems];
90 | }
91 |
92 | }
93 |
94 | -(NSMutableArray *)photoDataArray{
95 | if (!_photoDataArray) {
96 | _photoDataArray = [NSMutableArray array];
97 | }
98 | return _photoDataArray;
99 | }
100 |
101 | - (void)viewDidLoad {
102 | [super viewDidLoad];
103 | // Do any additional setup after loading the view.
104 |
105 | [self setupCollectionViewUI];
106 |
107 | [self setPageControlUI];
108 |
109 | [self loadPhotoData];
110 |
111 | if ([self.delegate respondsToSelector:@selector(zzbrowserPickerPhotoContent:)]) {
112 | [self.photoDataArray addObjectsFromArray:[self.delegate zzbrowserPickerPhotoContent:self]];
113 | }
114 | }
115 |
116 | -(void)loadPhotoData
117 | {
118 | if ([self.delegate respondsToSelector:@selector(zzbrowserPickerPhotoContent:)]) {
119 | [self.photoDataArray addObjectsFromArray:[self.delegate zzbrowserPickerPhotoContent:self]];
120 | }
121 | }
122 |
123 | /*
124 | * 更新数据刷新方法
125 | */
126 |
127 | -(void)reloadData
128 | {
129 |
130 | [_picBrowse reloadData];
131 | //照片总数通过delegate获取
132 | if ([self.delegate respondsToSelector:@selector(zzbrowserPickerPhotoNum:)]) {
133 | _numberOfItems = [self.delegate zzbrowserPickerPhotoNum:self];
134 | }
135 |
136 | //判断是否需要滚动到指定图片
137 | if (self.indexPath != nil) {
138 | _pageControl.pageControl.text = [NSString stringWithFormat:@"%ld / %ld",(long)self.indexPath.row + 1,(long)_numberOfItems];
139 | }else{
140 | _pageControl.pageControl.text = [NSString stringWithFormat:@"%d / %ld",1,(long)_numberOfItems];
141 | }
142 | }
143 |
144 | #pragma mark --- UICollectionviewDelegate or dataSource
145 | -(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
146 | {
147 | return 1;
148 | }
149 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
150 | {
151 | return [self.delegate zzbrowserPickerPhotoNum:self];
152 | }
153 |
154 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
155 | {
156 | ZZCameraBrowerCell *browerCell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([ZZCameraBrowerCell class]) forIndexPath:indexPath];
157 |
158 | browerCell.delegate = self;
159 |
160 | if ([[_photoDataArray objectAtIndex:indexPath.row] isKindOfClass:[ZZCamera class]]){
161 | ZZCamera *photo = [_photoDataArray objectAtIndex:indexPath.row];
162 | [browerCell loadPicData:photo.image];
163 | }
164 |
165 | return browerCell;
166 | }
167 |
168 | - (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
169 | if ([cell isKindOfClass:[ZZCameraBrowerCell class]]) {
170 | [(ZZCameraBrowerCell *)cell recoverSubview];
171 | }
172 | }
173 |
174 | - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
175 | if ([cell isKindOfClass:[ZZCameraBrowerCell class]]) {
176 | [(ZZCameraBrowerCell *)cell recoverSubview];
177 | }
178 | }
179 |
180 |
181 | -(void)clickSingleFingerAtScreen
182 | {
183 | [self dismissViewControllerAnimated:YES completion:nil];
184 | }
185 |
186 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView
187 | {
188 | int itemIndex = (scrollView.contentOffset.x + self.picBrowse.frame.size.width * 0.5) / self.picBrowse.frame.size.width;
189 | if (!self.numberOfItems) return;
190 | int indexOnPageControl = itemIndex % self.numberOfItems;
191 |
192 | _pageControl.pageControl.text = [NSString stringWithFormat:@"%d / %ld",indexOnPageControl+1,(long)_numberOfItems];
193 | self.pageControl.currentPage = indexOnPageControl;
194 | }
195 |
196 | -(void)showIn:(UIViewController *)controller
197 | {
198 | [controller presentViewController:self animated:YES completion:nil];
199 | }
200 |
201 | - (void)didReceiveMemoryWarning {
202 | [super didReceiveMemoryWarning];
203 | // Dispose of any resources that can be recreated.
204 | }
205 |
206 |
207 |
208 | @end
209 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/Controller/ZZCameraController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCameraController.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/18.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 |
12 | typedef void(^ZZCameraResult)(id responseObject);
13 |
14 | @interface ZZCameraController : NSObject
15 |
16 | /*
17 | * 设置是否将拍完过后的照片直接保存到相册
18 | */
19 | @property (assign, nonatomic) BOOL isSaveLocal;
20 |
21 | /*
22 | * 设置最多连拍张数
23 | */
24 | @property (assign, nonatomic) NSInteger takePhotoOfMax;
25 |
26 |
27 | /*
28 | * 设置相机页面主题颜色,默认为黑色
29 | */
30 | @property (strong, nonatomic) UIColor *themeColor;
31 |
32 | -(void)showIn:(UIViewController *)controller result:(ZZCameraResult)result;
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/Controller/ZZCameraController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCameraController.m
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/18.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import "ZZCameraController.h"
10 | #import "ZZCameraPickerViewController.h"
11 | @interface ZZCameraController()
12 |
13 | @property (strong,nonatomic) ZZCameraPickerViewController *cameraPickerController;
14 |
15 | @end
16 |
17 | @implementation ZZCameraController
18 |
19 | -(ZZCameraPickerViewController *)cameraPickerController
20 | {
21 | if (!_cameraPickerController) {
22 | _cameraPickerController = [[ZZCameraPickerViewController alloc]init];
23 | }
24 | return _cameraPickerController;
25 | }
26 |
27 | -(void)showIn:(UIViewController *)controller result:(ZZCameraResult)result
28 | {
29 | AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
30 |
31 | if (status == AVAuthorizationStatusNotDetermined) {
32 | //相机进行授权
33 | /* * * 第一次安装应用时直接进行这个判断进行授权 * * */
34 | [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
35 | if (granted) {
36 | dispatch_async(dispatch_get_main_queue(), ^{
37 | [self showController:controller result:result];
38 | });
39 | }
40 | }];
41 | }else if (status == AVAuthorizationStatusAuthorized){
42 | [self showController:controller result:result];
43 | }else if (status == AVAuthorizationStatusRestricted || status == AVAuthorizationStatusDenied){
44 | [self showAlertViewToController:controller];
45 | }
46 | }
47 |
48 | -(void)showController:(UIViewController *)controller result:(ZZCameraResult)result
49 | {
50 | self.cameraPickerController.CameraResult = result;
51 | //设置连拍最大张数
52 | self.cameraPickerController.takePhotoOfMax = self.takePhotoOfMax;
53 | //设置返回图片类型
54 | self.cameraPickerController.isSavelocal = self.isSaveLocal;
55 | self.cameraPickerController.themeColor = self.themeColor;
56 | [controller presentViewController:self.cameraPickerController animated:YES completion:nil];
57 | }
58 |
59 | -(void)showAlertViewToController:(UIViewController *)controller
60 | {
61 | NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
62 | // app名称
63 | NSString *app_Name = [infoDictionary objectForKey:@"CFBundleDisplayName"];
64 |
65 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提醒" message:[NSString stringWithFormat:@"请在iPhone的“设置->隐私->照片”开启%@访问你的相机",app_Name] preferredStyle:UIAlertControllerStyleAlert];
66 |
67 | UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
68 |
69 | }];
70 |
71 | [alert addAction:action1];
72 | [controller presentViewController:alert animated:YES completion:nil];
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/Controller/ZZCameraPickerViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCameraPickerViewController.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/18.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 |
12 | @interface ZZCameraPickerViewController : UIViewController
13 |
14 | @property (nonatomic, assign) BOOL isSavelocal;
15 |
16 | @property (nonatomic, assign) NSInteger takePhotoOfMax;
17 |
18 | @property (nonatomic, strong) UIColor *themeColor;
19 |
20 | @property (nonatomic, copy) void (^CameraResult)(id responseObject);
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/Model/ZZCamera.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCamera.h
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/25.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ZZCamera : NSObject
12 |
13 | /**
14 | 照片
15 | */
16 | @property (nonatomic, strong) UIImage *image;
17 |
18 | /**
19 | 照片保存到相册中的时间
20 | */
21 | @property (nonatomic, copy) NSDate *createDate;
22 |
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/Model/ZZCamera.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCamera.m
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/25.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "ZZCamera.h"
10 |
11 | @implementation ZZCamera
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/View/ZZCameraBrowerCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCameraBrowerCell.h
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/10/19.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol ZZCameraBrowerCellDelegate
12 |
13 | - (void) clickSingleFingerAtScreen;
14 |
15 | @end
16 |
17 | @interface ZZCameraBrowerCell : UICollectionViewCell
18 |
19 | @property (nonatomic, weak) iddelegate;
20 |
21 | -(void) loadPicData:(UIImage *) image;
22 |
23 | -(void) recoverSubview;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/View/ZZCameraBrowerCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCameraBrowerCell.m
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/10/19.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "ZZCameraBrowerCell.h"
10 |
11 | @interface ZZCameraBrowerCell()
12 | {
13 | CGFloat _browser_width;
14 | CGFloat _browser_height;
15 | }
16 | @property (nonatomic, strong) UIScrollView *scaleView;
17 | @property (nonatomic, strong) UIImageView *photo_image_view;
18 | @end
19 |
20 | @implementation ZZCameraBrowerCell
21 |
22 | -(instancetype)initWithFrame:(CGRect)frame
23 | {
24 | self = [super initWithFrame:frame];
25 | if (self) {
26 |
27 | _browser_width = frame.size.width;
28 | _browser_height = frame.size.height;
29 |
30 | _scaleView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, _browser_width, _browser_height)];
31 | _scaleView.delegate = self;
32 | _scaleView.maximumZoomScale = 2.5;
33 | _scaleView.minimumZoomScale = 1.0;
34 | _scaleView.bouncesZoom = YES;
35 | _scaleView.multipleTouchEnabled = YES;
36 | _scaleView.delegate = self;
37 | _scaleView.scrollsToTop = NO;
38 | _scaleView.showsHorizontalScrollIndicator = NO;
39 | _scaleView.showsVerticalScrollIndicator = NO;
40 | _scaleView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
41 | _scaleView.delaysContentTouches = NO;
42 | _scaleView.canCancelContentTouches = YES;
43 | _scaleView.alwaysBounceVertical = NO;
44 | [self.contentView addSubview:_scaleView];
45 |
46 | _photo_image_view = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, _browser_width, _browser_height)];
47 | _photo_image_view.contentMode = UIViewContentModeScaleAspectFit;
48 | _photo_image_view.userInteractionEnabled = YES;
49 | [_scaleView addSubview:_photo_image_view];
50 |
51 | UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapHandle:)];
52 | [_photo_image_view addGestureRecognizer:singleTap];
53 |
54 | UITapGestureRecognizer *doubleTap= [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapHandle:)];
55 | doubleTap.delegate = self;
56 | doubleTap.numberOfTapsRequired = 2;
57 | [_photo_image_view addGestureRecognizer:doubleTap];
58 |
59 | [singleTap requireGestureRecognizerToFail:doubleTap];
60 | }
61 | return self;
62 | }
63 |
64 |
65 | -(void)changeFrameWithImage:(UIImage *)image
66 | {
67 | CGFloat height = image.size.height / image.size.width * _browser_width;
68 | self.photo_image_view.frame = CGRectMake(0, 0, _browser_width, height);
69 | self.photo_image_view.center = CGPointMake(_browser_width / 2, _browser_height / 2);
70 | _scaleView.contentSize = CGSizeMake(_browser_width, MAX(self.photo_image_view.frame.size.height, _browser_height));
71 | }
72 |
73 | -(void)loadPicData:(UIImage *)image
74 | {
75 | if (image != nil) {
76 | [self changeFrameWithImage:image];
77 | _photo_image_view.image = image;
78 | }
79 | }
80 |
81 | -(void)recoverSubview
82 | {
83 | [_scaleView setZoomScale:1.0 animated:NO];
84 | }
85 |
86 | -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
87 | {
88 | return _photo_image_view;
89 | }
90 |
91 | -(void)scrollViewDidZoom:(UIScrollView *)scrollView
92 | {
93 | CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width)?
94 | (scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
95 | CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height)?
96 | (scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
97 | _photo_image_view.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX,
98 | scrollView.contentSize.height * 0.5 + offsetY);
99 | }
100 |
101 | -(void)singleTapHandle:(UITapGestureRecognizer *)sender
102 | {
103 | if ([self.delegate respondsToSelector:@selector(clickSingleFingerAtScreen)]) {
104 | [self.delegate clickSingleFingerAtScreen];
105 | }
106 | }
107 |
108 |
109 | - (void)doubleTapHandle:(UITapGestureRecognizer *)sender
110 | {
111 | if (_scaleView.zoomScale > 1.0) {
112 | [_scaleView setZoomScale:1.0 animated:YES];
113 | } else {
114 | CGPoint touchPoint = [sender locationInView:self.photo_image_view];
115 | CGFloat maxScale = _scaleView.maximumZoomScale;
116 | CGFloat xsize = self.frame.size.width / maxScale;
117 | CGFloat ysize = self.frame.size.height / maxScale;
118 | [_scaleView zoomToRect:CGRectMake(touchPoint.x - xsize/2, touchPoint.y - ysize/2, xsize, ysize) animated:YES];
119 | }
120 | }
121 |
122 | @end
123 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/View/ZZCameraFocusView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCameraFocusView.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/21.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class ZZCameraFocusView;
12 |
13 | @protocol ZZCameraFocusDelegate
14 |
15 | @optional
16 | -(void) cameraFocusOptionsWithPoint:(CGPoint)point;
17 |
18 | @end
19 |
20 | @interface ZZCameraFocusView : UIView
21 |
22 | @property (nonatomic,weak) id delegate;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/View/ZZCameraFocusView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCameraFocusView.m
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/21.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import "ZZCameraFocusView.h"
10 |
11 | @interface ZZCameraFocusView()
12 |
13 | @property (strong, nonatomic) UIImageView *focus;
14 | @property (strong, nonatomic) NSTimer *timer;
15 |
16 | @end
17 |
18 | @implementation ZZCameraFocusView
19 |
20 | -(instancetype)initWithFrame:(CGRect)frame
21 | {
22 | self = [super initWithFrame:frame];
23 | if (self) {
24 | self.backgroundColor = [UIColor clearColor];
25 |
26 | _focus = [[UIImageView alloc]init];
27 | _focus.image = [UIImage imageNamed:@"camera_focus_pic.png"];
28 | }
29 | return self;
30 | }
31 |
32 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
33 | {
34 | UITouch *touch = [touches anyObject];
35 | CGPoint point = [touch locationInView:touch.view];
36 | _focus.frame = CGRectMake(0, 0, 80, 80);
37 | _focus.center = point;
38 | [self addSubview:_focus];
39 |
40 | [self shakeToShow:_focus];
41 |
42 | _timer = [NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:@selector(hideFocusView) userInfo:nil repeats:YES];
43 | if ([self.delegate respondsToSelector:@selector(cameraFocusOptionsWithPoint:)]) {
44 | [self.delegate cameraFocusOptionsWithPoint:point];
45 | }
46 | }
47 |
48 | - (void) shakeToShow:(UIView*)aView{
49 | CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
50 | animation.duration = 0.5;
51 |
52 | NSMutableArray *values = [NSMutableArray array];
53 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)]];
54 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.2, 1.2, 1.0)]];
55 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9, 0.9, 1.0)]];
56 | [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1.0)]];
57 | animation.values = values;
58 | [aView.layer addAnimation:animation forKey:nil];
59 | }
60 |
61 | -(void) hideFocusView
62 | {
63 | [_focus removeFromSuperview];
64 | [_timer invalidate];
65 | }
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/View/ZZCameraPickerCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCameraPickerCell.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/18.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 | @interface ZZCameraPickerCell : UICollectionViewCell
12 |
13 | @property(strong,nonatomic) UIImageView *pics;
14 | @property(strong,nonatomic) UIButton *removeBtn;
15 |
16 | @property(copy ,nonatomic) void(^deleteBlock)();
17 |
18 | -(void)loadPhotoDatas:(UIImage *)image;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZCamera/View/ZZCameraPickerCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZCameraPickerCell.m
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/18.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import "ZZCameraPickerCell.h"
10 |
11 |
12 |
13 | @implementation ZZCameraPickerCell
14 |
15 | -(instancetype)initWithFrame:(CGRect)frame
16 | {
17 | self = [super initWithFrame:frame];
18 | if (self) {
19 |
20 |
21 | _pics = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, (ZZ_SCREEN_WIDTH - 60) / 5, (ZZ_SCREEN_WIDTH - 60) / 5)];
22 | _pics.contentMode = UIViewContentModeScaleAspectFill;
23 | [self.contentView addSubview:_pics];
24 |
25 |
26 | _removeBtn = [[UIButton alloc]initWithFrame:CGRectMake((ZZ_SCREEN_WIDTH - 60) / 5 -20, 0, 20, 20)];
27 | [_removeBtn setImage:Remove_Btn_Pic forState:UIControlStateNormal];
28 | [_removeBtn addTarget:self action:@selector(clickRemoveButtonMethod:) forControlEvents:UIControlEventTouchUpInside];
29 | [self.contentView addSubview:_removeBtn];
30 |
31 | }
32 | return self;
33 |
34 | }
35 |
36 | //载入数据
37 | -(void)loadPhotoDatas:(UIImage *)image
38 | {
39 | _pics.image = image;
40 |
41 | }
42 |
43 | -(void)clickRemoveButtonMethod:(UIButton *)button
44 | {
45 | self.deleteBlock();
46 | }
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/Controller/ZZPhotoBrowerViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoBrowerViewController.h
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/27.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 |
12 |
13 |
14 | @interface ZZPhotoBrowerViewController : UIViewController
15 |
16 | @property (nonatomic, copy) NSArray *photoData;
17 |
18 | @property (nonatomic, assign) NSInteger scrollIndex;
19 |
20 | -(void) showIn:(UIViewController *)controller;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/Controller/ZZPhotoBrowerViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoBrowerViewController.m
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/27.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "ZZPhotoBrowerViewController.h"
10 | #import "ZZPhotoBrowerCell.h"
11 | #import "ZZPageControl.h"
12 | #import "ZZPhoto.h"
13 |
14 |
15 | @interface ZZPhotoBrowerViewController ()
16 |
17 | @property (nonatomic, strong) UICollectionView *picBrowse;
18 | @property (nonatomic, assign) NSInteger numberOfItems;
19 | @property (nonatomic, strong) UIBarButtonItem *backBarButton;
20 | @end
21 |
22 | @implementation ZZPhotoBrowerViewController
23 |
24 | -(UIBarButtonItem *)backBarButton
25 | {
26 | if (!_backBarButton) {
27 | UIButton *back_btn = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 45, 44)];
28 | [back_btn setImage:[UIImage imageNamed:@"back_button_normal.png"] forState:UIControlStateNormal];
29 | [back_btn setImage:[UIImage imageNamed:@"back_button_high.png"] forState:UIControlStateHighlighted];
30 | back_btn.frame = CGRectMake(0, 0, 45, 44);
31 | [back_btn addTarget:self action:@selector(backItemMethod) forControlEvents:UIControlEventTouchUpInside];
32 |
33 | _backBarButton = [[UIBarButtonItem alloc] initWithCustomView:back_btn];
34 | }
35 | return _backBarButton;
36 | }
37 |
38 | -(void)backItemMethod
39 | {
40 | [self.navigationController popViewControllerAnimated:YES];
41 |
42 | }
43 |
44 | -(void) makeCollectionViewUI
45 | {
46 | self.edgesForExtendedLayout = UIRectEdgeNone;
47 | /*
48 | * 创建核心内容 UICollectionView
49 | */
50 | self.view.backgroundColor = [UIColor blackColor];
51 |
52 | UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
53 | flowLayout.itemSize = (CGSize){self.view.frame.size.width,self.view.frame.size.height-64};
54 | flowLayout.minimumLineSpacing = 0.0f;
55 | flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
56 |
57 | _picBrowse = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:flowLayout];
58 | _picBrowse.backgroundColor = [UIColor clearColor];
59 | _picBrowse.pagingEnabled = YES;
60 |
61 | _picBrowse.showsHorizontalScrollIndicator = NO;
62 | _picBrowse.showsVerticalScrollIndicator = NO;
63 | [_picBrowse registerClass:[ZZPhotoBrowerCell class] forCellWithReuseIdentifier:NSStringFromClass([ZZPhotoBrowerCell class])];
64 | _picBrowse.dataSource = self;
65 | _picBrowse.delegate = self;
66 | _picBrowse.translatesAutoresizingMaskIntoConstraints = NO;
67 | [self.view addSubview:_picBrowse];
68 |
69 | NSLayoutConstraint *list_top = [NSLayoutConstraint constraintWithItem:_picBrowse attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:0.0f];
70 |
71 | NSLayoutConstraint *list_bottom = [NSLayoutConstraint constraintWithItem:_picBrowse attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1 constant:0.0f];
72 |
73 | NSLayoutConstraint *list_left = [NSLayoutConstraint constraintWithItem:_picBrowse attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1 constant:0.0f];
74 |
75 | NSLayoutConstraint *list_right = [NSLayoutConstraint constraintWithItem:_picBrowse attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1 constant:0.0f];
76 |
77 | [self.view addConstraints:@[list_top,list_bottom,list_left,list_right]];
78 |
79 | }
80 |
81 | - (void) viewDidLoad {
82 | [super viewDidLoad];
83 | // Do any additional setup after loading the view.
84 |
85 | self.navigationItem.title = @"预览";
86 | self.navigationItem.leftBarButtonItem = self.backBarButton;
87 |
88 | [self makeCollectionViewUI];
89 |
90 | }
91 |
92 | -(void) viewDidLayoutSubviews
93 | {
94 | [super viewDidLayoutSubviews];
95 |
96 | //滚动到指定位置
97 |
98 | [_picBrowse scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:_scrollIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionRight animated:NO];
99 | }
100 |
101 | #pragma mark --- UICollectionviewDelegate or dataSource
102 | -(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView
103 | {
104 | return 1;
105 | }
106 | -(NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
107 | {
108 | return _photoData.count;
109 | }
110 |
111 | -(UICollectionViewCell *) collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
112 | {
113 | ZZPhotoBrowerCell *browerCell = [collectionView dequeueReusableCellWithReuseIdentifier:NSStringFromClass([ZZPhotoBrowerCell class]) forIndexPath:indexPath];
114 |
115 | if ([[_photoData objectAtIndex:indexPath.row] isKindOfClass:[ZZPhoto class]]) {
116 | //加载相册中的数据时实用
117 | ZZPhoto *photo = [_photoData objectAtIndex:indexPath.row];
118 | [browerCell loadPHAssetItemForPics:photo.asset];
119 | }
120 |
121 | return browerCell;
122 | }
123 |
124 | - (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
125 | if ([cell isKindOfClass:[ZZPhotoBrowerCell class]]) {
126 | [(ZZPhotoBrowerCell *)cell recoverSubview];
127 | }
128 | }
129 |
130 | - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
131 | if ([cell isKindOfClass:[ZZPhotoBrowerCell class]]) {
132 | [(ZZPhotoBrowerCell *)cell recoverSubview];
133 | }
134 | }
135 |
136 |
137 | -(void) showIn:(UIViewController *)controller
138 | {
139 | [controller.navigationController pushViewController:self animated:YES];
140 | }
141 |
142 | - (void)didReceiveMemoryWarning {
143 | [super didReceiveMemoryWarning];
144 | // Dispose of any resources that can be recreated.
145 | }
146 |
147 |
148 | @end
149 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/Controller/ZZPhotoController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoController.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/16.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 | /*
12 | * 设置Block
13 | */
14 | typedef void (^ZZPhotoResult)(id responseObject);
15 |
16 |
17 | @interface ZZPhotoController : NSObject
18 | /*
19 | * 设置圆点颜色
20 | */
21 | @property(strong,nonatomic) UIColor *roundColor;
22 | /*
23 | * 选择照片的最多张数
24 | */
25 | @property(assign,nonatomic) NSInteger selectPhotoOfMax;
26 | /*
27 | * 设置回调方法
28 | */
29 | -(void)showIn:(UIViewController *)controller result:(ZZPhotoResult)result;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/Controller/ZZPhotoController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoController.m
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/16.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import "ZZPhotoController.h"
10 | #import "ZZPhotoListViewController.h"
11 | #import "ZZPhotoPickerViewController.h"
12 |
13 | @interface ZZPhotoController()
14 |
15 | @property(strong,nonatomic) ZZPhotoListViewController *photoListController;
16 | @property(strong,nonatomic) UINavigationController *photoListNavigationController;
17 | @property(strong,nonatomic) ZZPhotoPickerViewController *photoPickerController;
18 |
19 | @end
20 |
21 | @implementation ZZPhotoController
22 |
23 | #pragma mark ---- 懒加载控制器
24 | -(ZZPhotoListViewController *)photoListController{
25 | if (!_photoListController) {
26 | _photoListController = [[ZZPhotoListViewController alloc]init];
27 | }
28 | return _photoListController;
29 | }
30 |
31 | -(UINavigationController *)photoListNavigationController{
32 | if (!_photoListNavigationController) {
33 | _photoListNavigationController = [[UINavigationController alloc]initWithRootViewController:self.photoListController];
34 | }
35 | return _photoListNavigationController;
36 | }
37 |
38 | -(ZZPhotoPickerViewController *)photoPickerController{
39 | if (!_photoPickerController) {
40 | _photoPickerController = [[ZZPhotoPickerViewController alloc]init];
41 | }
42 | return _photoPickerController;
43 | }
44 |
45 | #pragma mark ---- 弹出控制器
46 | -(void)showIn:(UIViewController *)controller result:(ZZPhotoResult)result{
47 |
48 | //相册权限判断
49 | PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
50 | if (status == PHAuthorizationStatusDenied) {
51 | //相册权限未开启
52 | [self showAlertViewToController:controller];
53 |
54 | }else if(status == PHAuthorizationStatusNotDetermined){
55 | //相册进行授权
56 | /* * * 第一次安装应用时直接进行这个判断进行授权 * * */
57 | [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status){
58 | //授权后直接打开照片库
59 | if (status == PHAuthorizationStatusAuthorized){
60 | dispatch_async(dispatch_get_main_queue(), ^{
61 | [self showController:controller result:result];
62 | });
63 |
64 | }
65 | }];
66 | }else if (status == PHAuthorizationStatusAuthorized){
67 | [self showController:controller result:result];
68 | }
69 | }
70 |
71 | -(void)showController:(UIViewController *)controller result:(ZZPhotoResult)result
72 | {
73 | //授权完成,打开相册
74 |
75 | self.photoListController.photoResult = result;
76 | //先向presentViewController控制器ZZPhotoListViewController,此控制器为全部相册控制器
77 |
78 | /* * * 同时设定最多选择照片的张数 * * */
79 | self.photoListController.selectNum = _selectPhotoOfMax;
80 |
81 | [self showPhotoList:controller];
82 |
83 | //Block传值
84 | self.photoPickerController.PhotoResult = result;
85 | self.photoPickerController.isAlubSeclect = NO;
86 | self.photoPickerController.roundColor = self.roundColor;
87 | /* * * 同时设定最多选择照片的张数 * * */
88 | self.photoPickerController.selectNum = _selectPhotoOfMax;
89 |
90 | //然后再执行pushViewController控制器ZZPhotoPickerViewController
91 | //此控制器为详情相册,显示某个相册中的详细照片
92 | [self showPhotoPicker:self.photoListController.navigationController];
93 | }
94 |
95 | -(void)showPhotoList:(UIViewController *)controller
96 | {
97 | [controller presentViewController:self.photoListNavigationController animated:YES completion:nil];
98 | }
99 |
100 | -(void)showPhotoPicker:(UINavigationController *)navigationController
101 | {
102 | //此处注意Animated == NO,关闭动画效果。则直接进入了详细页面。
103 | [navigationController pushViewController:self.photoPickerController animated:NO];
104 | }
105 |
106 | -(void)showAlertViewToController:(UIViewController *)controller
107 | {
108 | NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
109 | // app名称
110 | NSString *app_Name = [infoDictionary objectForKey:@"CFBundleDisplayName"];
111 |
112 | UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提醒" message:[NSString stringWithFormat:@"请在iPhone的“设置->隐私->照片”开启%@访问你的手机相册",app_Name] preferredStyle:UIAlertControllerStyleAlert];
113 |
114 | UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){
115 |
116 | }];
117 |
118 | [alert addAction:action1];
119 | [controller presentViewController:alert animated:YES completion:nil];
120 | }
121 |
122 | @end
123 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/Controller/ZZPhotoListViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoListViewController.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/17.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 | @interface ZZPhotoListViewController : UIViewController
12 |
13 | @property (nonatomic, assign) NSInteger selectNum;
14 | @property (nonatomic, copy) void (^photoResult)(id responseObject);
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/Controller/ZZPhotoListViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoListViewController.m
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/17.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import "ZZPhotoListViewController.h"
10 | #import "ZZPhotoDatas.h"
11 | #import "ZZPhotoListCell.h"
12 | #import "ZZPhotoPickerViewController.h"
13 | #import
14 | #import "ZZPhotoListModel.h"
15 |
16 | @interface ZZPhotoListViewController ()
17 |
18 | @property (nonatomic, strong) UITableView *alumbTable;
19 | @property (nonatomic, strong) PHPhotoLibrary *assetsLibrary;
20 | @property (nonatomic, copy) NSArray *alubms;
21 | @property (nonatomic, strong) UIBarButtonItem *closeBtn;
22 | @property (nonatomic, strong) ZZPhotoDatas *datas;
23 | @property (nonatomic, strong) ZZPhotoPickerViewController *photoPickerViewController;
24 | @end
25 |
26 | @implementation ZZPhotoListViewController
27 |
28 |
29 | -(UIBarButtonItem *)closeBtn{
30 | if (!_closeBtn) {
31 | UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 50, 44)];
32 | [button addTarget:self action:@selector(close) forControlEvents:UIControlEventTouchUpInside];
33 | button.titleLabel.font = [UIFont systemFontOfSize:17.0f];
34 | [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
35 | [button setTitle:@"关闭" forState:UIControlStateNormal];
36 | [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
37 |
38 | _closeBtn = [[UIBarButtonItem alloc] initWithCustomView:button];
39 | }
40 | return _closeBtn;
41 | }
42 |
43 | -(void)close{
44 | [self dismissViewControllerAnimated:YES completion:nil];
45 | }
46 |
47 | #pragma mark --- 懒加载
48 | -(ZZPhotoDatas *)datas{
49 | if (!_datas) {
50 | _datas = [[ZZPhotoDatas alloc]init];
51 | }
52 | return _datas;
53 | }
54 |
55 | -(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
56 | {
57 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
58 | if (self) {
59 |
60 | self.navigationItem.title = @"相册";
61 | }
62 | return self;
63 | }
64 |
65 | - (void)viewDidLoad {
66 | [super viewDidLoad];
67 | // Do any additional setup after loading the view.
68 |
69 | self.navigationItem.rightBarButtonItem = self.closeBtn;
70 | self.edgesForExtendedLayout = UIRectEdgeNone;
71 |
72 | _photoPickerViewController = [ZZPhotoPickerViewController new];
73 |
74 | [self makeAlumListUI];
75 |
76 |
77 | [self.datas fetchPhotoListDatasCompletion:^(NSArray *data) {
78 | self.alubms = data;
79 | }];
80 | }
81 |
82 | -(void)viewWillAppear:(BOOL)animated
83 | {
84 | [super viewWillAppear:animated];
85 | [self.alumbTable deselectRowAtIndexPath:[self.alumbTable indexPathForSelectedRow] animated:YES];
86 | }
87 |
88 | -(void) makeAlumListUI
89 | {
90 | _alumbTable = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStylePlain];
91 | _alumbTable.delegate = self;
92 | _alumbTable.dataSource = self;
93 | _alumbTable.separatorStyle = NO;
94 | _alumbTable.translatesAutoresizingMaskIntoConstraints = NO;
95 | [self.view addSubview:_alumbTable];
96 |
97 | NSLayoutConstraint *list_top = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_alumbTable attribute:NSLayoutAttributeTop multiplier:1 constant:0.0f];
98 |
99 | NSLayoutConstraint *list_bottom = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:_alumbTable attribute:NSLayoutAttributeBottom multiplier:1 constant:0.0f];
100 |
101 | NSLayoutConstraint *list_left = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:_alumbTable attribute:NSLayoutAttributeLeft multiplier:1 constant:0.0f];
102 |
103 | NSLayoutConstraint *list_right = [NSLayoutConstraint constraintWithItem:self.view attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:_alumbTable attribute:NSLayoutAttributeRight multiplier:1 constant:0.0f];
104 |
105 | [self.view addConstraints:@[list_top,list_bottom,list_left,list_right]];
106 | }
107 |
108 | #pragma mark --- UITableView协议方法
109 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
110 | {
111 | return 1;
112 | }
113 |
114 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
115 | {
116 | return self.alubms.count;
117 | }
118 |
119 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
120 | {
121 | ZZPhotoListCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ZZPhotoListCell"];
122 | if (!cell) {
123 | cell = [[ZZPhotoListCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"ZZPhotoListCell"];
124 | }
125 |
126 | [cell loadPhotoListData:[self.alubms objectAtIndex:indexPath.row]];
127 |
128 | return cell;
129 | }
130 |
131 | -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
132 | {
133 | return 70;
134 | }
135 |
136 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
137 | {
138 | _photoPickerViewController.PhotoResult = self.photoResult;
139 | _photoPickerViewController.selectNum = self.selectNum;
140 | ZZPhotoListModel *listmodel = [self.alubms objectAtIndex:indexPath.row];
141 | _photoPickerViewController.alumbModel = listmodel;
142 | _photoPickerViewController.navigationItem.title = listmodel.title;
143 | _photoPickerViewController.isAlubSeclect = YES;
144 | [self.navigationController pushViewController:_photoPickerViewController animated:YES];
145 | }
146 |
147 | - (void)didReceiveMemoryWarning {
148 | [super didReceiveMemoryWarning];
149 | // Dispose of any resources that can be recreated.
150 | }
151 |
152 | @end
153 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/Controller/ZZPhotoPickerViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoPickerViewController.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/7/7.
6 | // Copyright (c) 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 | #import "ZZPhotoListModel.h"
12 |
13 | @interface ZZPhotoPickerViewController : UIViewController
14 |
15 | @property (nonatomic, copy) void (^PhotoResult)(id responseObject);
16 | @property (nonatomic, assign) BOOL isAlubSeclect;
17 | @property (nonatomic, strong) UIColor *roundColor;
18 | @property (nonatomic, assign) NSInteger selectNum;
19 | @property (nonatomic, strong) ZZPhotoListModel *alumbModel;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/Model/ZZPhoto.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhoto.h
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/25.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 | @interface ZZPhoto : NSObject
12 |
13 | /**
14 | 资源
15 | */
16 | @property (nonatomic, strong) PHAsset *asset;
17 | /**
18 | 原尺寸图片
19 | */
20 | @property (nonatomic, strong) UIImage *originImage;
21 | /**
22 | 照片在手机中的路径
23 | */
24 | @property (nonatomic, strong) NSURL *imageUrl;
25 | /**
26 | 照片保存到相册中的时间
27 | */
28 | @property (nonatomic, copy) NSDate *createDate;
29 | /**
30 | 判断该图片是否选中
31 | */
32 | @property (nonatomic, assign) BOOL isSelect;
33 |
34 | +(UIImage *) fetchThumbImageWithAsset:(PHAsset *)asset;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/Model/ZZPhoto.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhoto.m
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/25.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "ZZPhoto.h"
10 |
11 | @implementation ZZPhoto
12 |
13 | +(UIImage *) fetchThumbImageWithAsset:(PHAsset *)asset
14 | {
15 | __block UIImage *thumbImage;
16 | [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:CGSizeMake(200, 200) contentMode:PHImageContentModeAspectFit options:nil resultHandler:^(UIImage *result, NSDictionary *info){
17 | BOOL downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
18 |
19 | //设置BOOL判断,确定返回高清照片
20 | if (downloadFinined) {
21 |
22 | thumbImage = result;
23 | }
24 |
25 | }];
26 |
27 | return thumbImage;
28 | }
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/Model/ZZPhotoDatas.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoDatas.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/17.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 | @interface ZZPhotoDatas : NSObject
12 | /**
13 | 获取全部相册
14 |
15 | @return array 集合
16 | */
17 | - (void) fetchPhotoListDatasCompletion:(void(^)(NSArray *data))completion;
18 |
19 | /**
20 | 获取某个相册的全部照片实体
21 |
22 | @param collection 相册集合
23 |
24 | @return 相册中全部实体
25 | */
26 | - (PHFetchResult *) GetFetchResult:(PHAssetCollection *)collection;
27 |
28 | /**
29 | 获取图片实体,并把图片结果存放到数组中,返回值数组
30 |
31 | @param fetchResult
32 |
33 | @return array 集合
34 | */
35 | - (void)fetchPhotoAssets:(PHFetchResult *)fetchResult completion:(void(^)(NSArray *data))completion;
36 |
37 | /**
38 | 获取相机胶卷中的结果集
39 |
40 | @return 集合
41 | */
42 | - (PHFetchResult *) fetchCameraRollFetchResult;
43 |
44 | /**
45 | 回调方法使用数组
46 |
47 | @param asset 照片实体
48 | @param complection 回调方法
49 | */
50 | - (void) fetchImageObject:(id)asset complection:(void (^)(UIImage *,NSURL *))complection;
51 |
52 | /**
53 | 检测是否为iCloud资源
54 |
55 | @param asset 照片实体
56 |
57 | @return 是否
58 | */
59 | - (BOOL) CheckIsiCloudAsset:(PHAsset *)asset;
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/Model/ZZPhotoListModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoListModel.h
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/19.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 | @interface ZZPhotoListModel : NSObject
12 |
13 | /**
14 | 照片总数
15 | */
16 | @property (nonatomic, assign) NSInteger count;
17 |
18 | /**
19 | 集合中最后一个实体
20 | */
21 | @property (nonatomic, strong) PHAsset *lastObject;
22 | /**
23 | 相册名称
24 | */
25 | @property (nonatomic, copy) NSString *title;
26 | /**
27 | 结果集
28 | */
29 | @property (nonatomic, strong) PHFetchResult *fetchResult;
30 | /**
31 | 照片实体集合
32 | */
33 | @property (nonatomic, strong) PHAssetCollection *assetCollection;
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/Model/ZZPhotoListModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoListModel.m
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/5/19.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "ZZPhotoListModel.h"
10 |
11 | @implementation ZZPhotoListModel
12 |
13 |
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/View/ZZPhotoAlert.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoAlert.h
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/8/28.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ZZPhotoAlert : UIView
12 |
13 | +(ZZPhotoAlert *) sharedAlert;
14 |
15 | -(void) showPhotoAlert;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/View/ZZPhotoAlert.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoAlert.m
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/8/28.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "ZZPhotoAlert.h"
10 | #import "ZZResourceConfig.h"
11 | @implementation ZZPhotoAlert
12 |
13 | +(ZZPhotoAlert *)sharedAlert
14 | {
15 | static ZZPhotoAlert *photoAlert = nil;
16 | static dispatch_once_t onceToken;
17 | dispatch_once(&onceToken, ^{
18 | photoAlert = [[ZZPhotoAlert alloc]init];
19 | });
20 | return photoAlert;
21 | }
22 |
23 | -(instancetype)initWithFrame:(CGRect)frame
24 | {
25 | self = [super initWithFrame:frame];
26 | if (self) {
27 |
28 | self.frame = CGRectMake(0, 0, ZZ_SCREEN_WIDTH, ZZ_SCREEN_HEIGHT);
29 |
30 |
31 |
32 | }
33 | return self;
34 | }
35 |
36 | -(void) showPhotoAlert
37 | {
38 | [[UIApplication sharedApplication].keyWindow addSubview:self];
39 |
40 | UILabel *alertlabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0,0,0)];
41 |
42 | alertlabel.textColor = [UIColor whiteColor];
43 |
44 | alertlabel.textAlignment = NSTextAlignmentCenter;
45 |
46 | [alertlabel setNumberOfLines:0];
47 |
48 | NSString *alertText = @"温馨提示\n该图片尚未从iCloud中下载\n下载到本地后重试";
49 |
50 | alertlabel.text = alertText;
51 |
52 | alertlabel.textAlignment = NSTextAlignmentCenter;
53 |
54 | UIFont *font = [UIFont fontWithName:@"HelveticaNeue" size:16];
55 |
56 | alertlabel.font = font;
57 |
58 | CGSize labelsize = [alertText sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:font,NSFontAttributeName, nil]];
59 |
60 |
61 | [alertlabel setFrame:CGRectMake(8, 8, labelsize.width, labelsize.height)];
62 |
63 | UIView * alertView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, labelsize.width + 16, labelsize.height +16)];
64 |
65 | alertView.center = CGPointMake([UIScreen mainScreen].bounds.size.width / 2, [UIScreen mainScreen].bounds.size.height / 2);
66 |
67 | alertView.backgroundColor = [UIColor blackColor];
68 |
69 | alertView.alpha = 1;
70 |
71 | alertView.layer.masksToBounds = YES;
72 |
73 | alertView.layer.cornerRadius = 4;
74 |
75 | [alertView addSubview:alertlabel];
76 |
77 | [self addSubview:alertView];
78 |
79 | [UIView animateWithDuration:3.0f
80 | delay:0
81 | options:UIViewAnimationCurveEaseIn | UIViewAnimationOptionAllowUserInteraction
82 | animations:^{
83 |
84 | alertView.alpha = 0;
85 |
86 | }
87 | completion:^(BOOL finished){
88 | if(alertView.alpha == 0) {
89 |
90 | [self removeFromSuperview];
91 |
92 | }
93 | }];
94 |
95 | }
96 |
97 | @end
98 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/View/ZZPhotoBrowerCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoBrowerCell.h
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/10/19.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 |
12 | @interface ZZPhotoBrowerCell : UICollectionViewCell
13 |
14 | -(void)loadPHAssetItemForPics:(PHAsset *)assetItem;
15 |
16 | -(void)recoverSubview;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/View/ZZPhotoBrowerCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoBrowerCell.m
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/10/19.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "ZZPhotoBrowerCell.h"
10 |
11 | @interface ZZPhotoBrowerCell()
12 | {
13 | CGFloat _browser_width;
14 | CGFloat _browser_height;
15 | }
16 | @property (nonatomic, strong) UIScrollView *scaleView;
17 |
18 | @property (nonatomic, strong) UIImageView *photo_image_view;
19 |
20 | @end
21 |
22 | @implementation ZZPhotoBrowerCell
23 |
24 | -(instancetype)initWithFrame:(CGRect)frame
25 | {
26 | self = [super initWithFrame:frame];
27 | if (self) {
28 |
29 | _browser_width = frame.size.width;
30 | _browser_height = frame.size.height;
31 |
32 | _scaleView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, _browser_width, _browser_height)];
33 | _scaleView.delegate = self;
34 | _scaleView.maximumZoomScale = 2.5;
35 | _scaleView.minimumZoomScale = 1.0;
36 | _scaleView.bouncesZoom = YES;
37 | _scaleView.multipleTouchEnabled = YES;
38 | _scaleView.delegate = self;
39 | _scaleView.scrollsToTop = NO;
40 | _scaleView.showsHorizontalScrollIndicator = NO;
41 | _scaleView.showsVerticalScrollIndicator = NO;
42 | _scaleView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
43 | _scaleView.delaysContentTouches = NO;
44 | _scaleView.canCancelContentTouches = YES;
45 | _scaleView.alwaysBounceVertical = NO;
46 | _scaleView.userInteractionEnabled = YES;
47 | [self.contentView addSubview:_scaleView];
48 |
49 | _photo_image_view = [[UIImageView alloc]init];
50 | _photo_image_view.userInteractionEnabled = YES;
51 | _photo_image_view.contentMode = UIViewContentModeScaleAspectFit;
52 | [_scaleView addSubview:_photo_image_view];
53 |
54 | UITapGestureRecognizer *singleFingerOne = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleFingerEvent:)];
55 | singleFingerOne.delegate = self;
56 | singleFingerOne.numberOfTapsRequired = 1;
57 | [_photo_image_view addGestureRecognizer:singleFingerOne];
58 |
59 |
60 | UITapGestureRecognizer *singleFingerTwo = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleFingerEvent:)];
61 | singleFingerTwo.delegate = self;
62 | singleFingerTwo.numberOfTapsRequired = 2;
63 | [_photo_image_view addGestureRecognizer:singleFingerTwo];
64 |
65 | }
66 | return self;
67 | }
68 |
69 | -(void)loadPHAssetItemForPics:(PHAsset *)assetItem
70 | {
71 | __weak typeof (self) weakSelf = self;
72 | PHAsset *phAsset = (PHAsset *)assetItem;
73 | CGFloat photoWidth = [UIScreen mainScreen].bounds.size.width;
74 | CGFloat aspectRatio = phAsset.pixelWidth / (CGFloat)phAsset.pixelHeight;
75 | CGFloat multiple = [UIScreen mainScreen].scale;
76 | CGFloat pixelWidth = photoWidth * multiple;
77 | CGFloat pixelHeight = pixelWidth / aspectRatio;
78 |
79 | PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
80 | option.resizeMode = PHImageRequestOptionsResizeModeFast;
81 |
82 | [[PHImageManager defaultManager] requestImageForAsset:phAsset targetSize:CGSizeMake(pixelWidth, pixelHeight) contentMode:PHImageContentModeAspectFit options:option resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
83 |
84 | BOOL downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
85 |
86 | if (downloadFinined) {
87 |
88 | if (result != nil) {
89 | [weakSelf changeFrameWithImage:result];
90 | weakSelf.photo_image_view.image = result;
91 | }
92 | }
93 |
94 | }];
95 | }
96 |
97 | -(void)changeFrameWithImage:(UIImage *)image
98 | {
99 | CGFloat height = image.size.height / image.size.width * _browser_width;
100 | self.photo_image_view.frame = CGRectMake(0, 0, _browser_width, height);
101 | self.photo_image_view.center = CGPointMake(_browser_width / 2, _browser_height / 2);
102 | _scaleView.contentSize = CGSizeMake(_browser_width, MAX(self.photo_image_view.frame.size.height, _browser_height));
103 | }
104 |
105 | -(void)recoverSubview
106 | {
107 | [_scaleView setZoomScale:1.0 animated:NO];
108 | }
109 |
110 | -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
111 | {
112 | return _photo_image_view;
113 | }
114 |
115 | -(void)scrollViewDidZoom:(UIScrollView *)scrollView
116 | {
117 | CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width)?
118 | (scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
119 | CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height)?
120 | (scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
121 | _photo_image_view.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX,
122 | scrollView.contentSize.height * 0.5 + offsetY);
123 | }
124 |
125 | - (void)handleSingleFingerEvent:(UITapGestureRecognizer *)sender
126 | {
127 | if (sender.numberOfTapsRequired == 1) {
128 |
129 | }else if(sender.numberOfTapsRequired == 2){
130 |
131 | if (_scaleView.zoomScale > 1.0) {
132 | [_scaleView setZoomScale:1.0 animated:YES];
133 | } else {
134 | CGPoint touchPoint = [sender locationInView:self.photo_image_view];
135 | CGFloat maxScale = _scaleView.maximumZoomScale;
136 | CGFloat xsize = self.frame.size.width / maxScale;
137 | CGFloat ysize = self.frame.size.height / maxScale;
138 | [_scaleView zoomToRect:CGRectMake(touchPoint.x - xsize/2, touchPoint.y - ysize/2, xsize, ysize) animated:YES];
139 | }
140 |
141 | }
142 | }
143 |
144 |
145 | @end
146 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/View/ZZPhotoHud.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoHud.h
3 | // ZZPhotoKit
4 | //
5 | // Created by Yuan on 16/1/14.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ZZPhotoHud : UIView
12 |
13 | +(ZZPhotoHud *)sharedHud;
14 |
15 | +(void)showActiveHud;
16 | +(void)hideActiveHud;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/View/ZZPhotoHud.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoHud.m
3 | // ZZPhotoKit
4 | //
5 | // Created by Yuan on 16/1/14.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "ZZPhotoHud.h"
10 |
11 | @interface ZZPhotoHud()
12 |
13 | @property (strong ,nonatomic) UIView *hudView;
14 | @property (strong ,nonatomic) UIActivityIndicatorView *indicatorView;
15 | @property (strong ,nonatomic) UILabel *hudLabel;
16 |
17 | @end
18 |
19 | @implementation ZZPhotoHud
20 |
21 | +(ZZPhotoHud *)sharedHud
22 | {
23 | static ZZPhotoHud *_photoHud = nil;
24 | static dispatch_once_t onceToken;
25 | dispatch_once(&onceToken, ^{
26 | _photoHud = [[ZZPhotoHud alloc]init];
27 | });
28 | return _photoHud;
29 | }
30 |
31 | -(instancetype)init
32 | {
33 | self = [super init];
34 | if (self) {
35 |
36 | }
37 | return self;
38 | }
39 |
40 | -(void)show
41 | {
42 | [[UIApplication sharedApplication].keyWindow addSubview:self];
43 |
44 | [self makeInitUI];
45 |
46 | [self makeHudUI];
47 | }
48 |
49 | -(void) makeInitUI
50 | {
51 | //清楚整个背景颜色
52 | self.backgroundColor = [UIColor clearColor];
53 | self.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
54 | }
55 |
56 | -(void) makeHudUI
57 | {
58 | _hudView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 120, 90)];
59 | _hudView.center = CGPointMake([UIScreen mainScreen].bounds.size.width / 2, [UIScreen mainScreen].bounds.size.height / 2);
60 | _hudView.layer.cornerRadius = 8;
61 | _hudView.clipsToBounds = YES;
62 | _hudView.backgroundColor = [UIColor blackColor];
63 | _hudView.alpha = 0.8;
64 | [self addSubview:_hudView];
65 |
66 | _indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
67 | _indicatorView.frame = CGRectMake(45, 15, 30, 30);
68 | [_hudView addSubview:_indicatorView];
69 | [_indicatorView startAnimating];
70 |
71 | _hudLabel = [[UILabel alloc] init];
72 | _hudLabel.frame = CGRectMake(0,40, 120, 50);
73 | _hudLabel.textAlignment = NSTextAlignmentCenter;
74 | _hudLabel.text = @"图片处理中...";
75 | _hudLabel.font = [UIFont systemFontOfSize:15];
76 | _hudLabel.textColor = [UIColor whiteColor];
77 | [_hudView addSubview:_hudLabel];
78 | }
79 |
80 | -(void) removeHudUI;
81 | {
82 | [self removeFromSuperview];
83 | [_indicatorView stopAnimating];
84 | }
85 |
86 | +(void)showActiveHud
87 | {
88 | [[self sharedHud] show];
89 | }
90 |
91 | +(void)hideActiveHud
92 | {
93 | [[self sharedHud] removeHudUI];
94 | }
95 |
96 | @end
97 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/View/ZZPhotoListCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoListCell.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/17.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 | @interface ZZPhotoListCell : UITableViewCell
12 | /*
13 | * 相册图片,显示相册的最后一张图片
14 | */
15 | @property(strong,nonatomic) UIImageView *coverImage;
16 | /*
17 | * 相册标题,显示相册的标题
18 | */
19 | @property(strong,nonatomic) UILabel *title;
20 | /*
21 | * 相册副标题,显示相册中含有多少张图片
22 | */
23 | @property(strong,nonatomic) UILabel *subTitle;
24 |
25 | /*
26 | * 加载数据方法
27 | */
28 |
29 | -(void)loadPhotoListData:(PHAssetCollection *)assetItem;
30 | @end
31 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/View/ZZPhotoListCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoListCell.m
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/12/17.
6 | // Copyright © 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import "ZZPhotoListCell.h"
10 | #import "ZZPhotoListModel.h"
11 | @implementation ZZPhotoListCell
12 |
13 | -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
14 | {
15 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
16 | if (self) {
17 |
18 | _coverImage = [[UIImageView alloc]initWithFrame:CGRectMake(10, 5, 60, 60)];
19 |
20 | _coverImage.layer.masksToBounds = YES;
21 |
22 | _coverImage.contentMode = UIViewContentModeScaleAspectFill;
23 |
24 | [self.contentView addSubview:_coverImage];
25 |
26 | CGFloat labelWidth = [UIScreen mainScreen].bounds.size.width - 90;
27 |
28 | _title = [[UILabel alloc]initWithFrame:CGRectMake(80, 5, labelWidth, 25)];
29 |
30 | _title.textColor = [UIColor blackColor];
31 |
32 | [self.contentView addSubview:_title];
33 |
34 | _subTitle = [[UILabel alloc]initWithFrame:CGRectMake(80, 40, labelWidth, 25)];
35 |
36 | _subTitle.textColor = [UIColor blackColor];
37 |
38 | [self.contentView addSubview:_subTitle];
39 |
40 | CGFloat right = [UIScreen mainScreen].bounds.size.width;
41 |
42 | UIImageView *right_Cell = [[UIImageView alloc]initWithFrame:CGRectMake(right - 29, 25, 9, 20)];
43 |
44 | right_Cell.image = PhotoListRightBtn;
45 |
46 | [self.contentView addSubview:right_Cell];
47 |
48 | }
49 | return self;
50 | }
51 |
52 |
53 | -(void)loadPhotoListData:(ZZPhotoListModel *)listmodel
54 | {
55 | if ([listmodel isKindOfClass:[ZZPhotoListModel class]]) {
56 |
57 | [[PHImageManager defaultManager] requestImageForAsset:listmodel.lastObject targetSize:CGSizeMake(200,200) contentMode:PHImageContentModeDefault options:nil resultHandler:^(UIImage *result, NSDictionary *info)
58 | {
59 | if (result == nil) {
60 | self.coverImage.image = NOPhoto_Data_Pic;
61 | }else{
62 | self.coverImage.image = result;
63 | }
64 |
65 | }];
66 | self.title.text = listmodel.title;
67 | self.subTitle.text = [NSString stringWithFormat:@"%lu",(unsigned long)listmodel.count];
68 | }
69 | }
70 | @end
71 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/View/ZZPhotoPickerCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoPickerCell.h
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/7/7.
6 | // Copyright (c) 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ZZResourceConfig.h"
11 | #import "ZZPhoto.h"
12 |
13 | @interface ZZPhotoPickerCell : UICollectionViewCell
14 |
15 | @property(strong,nonatomic) UIImageView *photo;
16 | @property(strong,nonatomic) UIButton *selectBtn;
17 |
18 | @property(copy ,nonatomic) void(^selectBlock)();
19 |
20 | @property(assign,nonatomic) BOOL isSelect;
21 |
22 | -(void)loadPhotoData:(ZZPhoto *)photo;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/View/ZZPhotoPickerCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoPickerCell.m
3 | // ZZFramework
4 | //
5 | // Created by Yuan on 15/7/7.
6 | // Copyright (c) 2015年 zzl. All rights reserved.
7 | //
8 |
9 | #import "ZZPhotoPickerCell.h"
10 | #import "ZZAlumAnimation.h"
11 | @implementation ZZPhotoPickerCell
12 | -(instancetype)initWithFrame:(CGRect)frame
13 | {
14 | self = [super initWithFrame:frame];
15 | if (self) {
16 |
17 |
18 | _photo = [[UIImageView alloc]initWithFrame:self.bounds];
19 |
20 | _photo.layer.masksToBounds = YES;
21 |
22 | _photo.contentMode = UIViewContentModeScaleAspectFill;
23 |
24 | [self.contentView addSubview:_photo];
25 |
26 |
27 | CGFloat btnSize = self.frame.size.width / 4;
28 |
29 | _selectBtn = [[UIButton alloc]initWithFrame:CGRectMake(self.frame.size.width - btnSize - 5, 5, btnSize, btnSize)];
30 | [_selectBtn addTarget:self action:@selector(selectPhotoButtonMethod:) forControlEvents:UIControlEventTouchUpInside];
31 | [self.contentView addSubview:_selectBtn];
32 |
33 | }
34 | return self;
35 | }
36 |
37 | -(void) selectPhotoButtonMethod:(UIButton *)sender
38 | {
39 | [[ZZAlumAnimation sharedAnimation] selectAnimation:sender];
40 | self.selectBlock();
41 |
42 | }
43 |
44 | -(void)setIsSelect:(BOOL)isSelect
45 | {
46 | if (isSelect == YES) {
47 | [_selectBtn setImage:Pic_Btn_Selected forState:UIControlStateNormal];
48 | }else{
49 | [_selectBtn setImage:Pic_btn_UnSelected forState:UIControlStateNormal];
50 | }
51 | }
52 |
53 |
54 | -(void)loadPhotoData:(ZZPhoto *)photo
55 | {
56 | if (photo.isSelect == YES) {
57 | [_selectBtn setImage:Pic_Btn_Selected forState:UIControlStateNormal];
58 | }else{
59 | [_selectBtn setImage:Pic_btn_UnSelected forState:UIControlStateNormal];
60 | }
61 |
62 | if ([photo isKindOfClass:[ZZPhoto class]]) {
63 |
64 | [[PHImageManager defaultManager] requestImageForAsset:photo.asset targetSize:CGSizeMake(200, 200) contentMode:PHImageContentModeAspectFit options:nil resultHandler:^(UIImage *result, NSDictionary *info){
65 |
66 | self.photo.image = result;
67 |
68 | }];
69 |
70 | }
71 | }
72 | @end
73 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/View/ZZPhotoPickerFooterView.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoPickerFooterView.h
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/10/12.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ZZPhotoPickerFooterView : UICollectionReusableView
12 |
13 | @property (nonatomic, assign) NSInteger total_photo_num;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhoto/View/ZZPhotoPickerFooterView.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoPickerFooterView.m
3 | // ZZPhotoKit
4 | //
5 | // Created by 袁亮 on 16/10/12.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import "ZZPhotoPickerFooterView.h"
10 | #import "ZZResourceConfig.h"
11 |
12 | @interface ZZPhotoPickerFooterView()
13 |
14 | @property (nonatomic, strong) UILabel *totalNumLabel;
15 |
16 | @end
17 |
18 | @implementation ZZPhotoPickerFooterView
19 |
20 | -(instancetype)initWithFrame:(CGRect)frame
21 | {
22 | self = [super initWithFrame:frame];
23 | if (self) {
24 |
25 | [self makeFooterViewUI];
26 |
27 | }
28 | return self;
29 | }
30 |
31 | -(void) makeFooterViewUI
32 | {
33 | _totalNumLabel = [[UILabel alloc]initWithFrame:CGRectZero];
34 | _totalNumLabel.textColor = [UIColor blackColor];
35 | _totalNumLabel.textAlignment = NSTextAlignmentCenter;
36 | _totalNumLabel.translatesAutoresizingMaskIntoConstraints = NO;
37 | [self addSubview:_totalNumLabel];
38 |
39 | NSLayoutConstraint *total_label_left = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:_totalNumLabel attribute:NSLayoutAttributeLeft multiplier:1 constant:0.0f];
40 |
41 | NSLayoutConstraint *total_label_right = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:_totalNumLabel attribute:NSLayoutAttributeRight multiplier:1 constant:0.0f];
42 |
43 | NSLayoutConstraint *total_label_top = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_totalNumLabel attribute:NSLayoutAttributeTop multiplier:1 constant:0.0f];
44 |
45 | NSLayoutConstraint *total_label_bottom = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:_totalNumLabel attribute:NSLayoutAttributeBottom multiplier:1 constant:0.0f];
46 |
47 |
48 | [self addConstraints:@[total_label_left,total_label_right,total_label_top,total_label_bottom]];
49 |
50 | }
51 |
52 | -(void)setTotal_photo_num:(NSInteger)total_photo_num
53 | {
54 | _totalNumLabel.text = [NSString stringWithFormat:Total_Photo_Num,total_photo_num];
55 | }
56 |
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/ZZPhotoKit/ZZPhotoKit/ZZPhotoKit.h:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoKit.h
3 | // ZZPhotoKit
4 | //
5 | // Created by Yuan on 16/1/14.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #ifndef ZZPhotoKit_h
10 | #define ZZPhotoKit_h
11 |
12 | #import "ZZPhotoController.h"
13 | #import "ZZCameraController.h"
14 | #import "ZZBrowserPickerViewController.h"
15 |
16 | #import "ZZPhoto.h"
17 | #import "ZZCamera.h"
18 |
19 | /*
20 | # ZZPhotoKit
21 | ##说明
22 |
23 | * 此开源目前接近于成熟状态,不喜欢的大神们还望轻虐。
24 | * 注意此框架只支持 IOS 8.0 及以上系统使用。
25 | * 注意由于工作原因后续不做IOS7适配了,IOS7占有率也比较低了,所以也不考虑后续再做了。
26 | * 这次升级了版本之后以后可能不会有太大变动的。
27 | * 相册多选基于最新的 Photos 框架。
28 | * 相机连续拍摄基于AVFundation 框架。
29 | * 图片浏览器支持 SDWebImage 加载图片
30 | * 欢迎大家使用,欢迎大家Star
31 |
32 | ###告诉我您的APP,使用到我框架的把APP名字告诉我,谢谢哦。单纯看看使用率。(*^__^*)
33 | ###有什么不明白的地方,或者哪里需要改进的可以联系我
34 | ###联系方式
35 | ###关注微博:袁亮_ QQ:412016060
36 |
37 | */
38 |
39 |
40 | #endif /* ZZPhotoKit_h */
41 |
--------------------------------------------------------------------------------
/ZZPhotoKit/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // ZZPhotoKit
4 | //
5 | // Created by Yuan on 16/1/4.
6 | // Copyright © 2016年 Ace. 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 |
--------------------------------------------------------------------------------
/ZZPhotoKitTests/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 |
--------------------------------------------------------------------------------
/ZZPhotoKitTests/ZZPhotoKitTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoKitTests.m
3 | // ZZPhotoKitTests
4 | //
5 | // Created by Yuan on 16/1/4.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ZZPhotoKitTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation ZZPhotoKitTests
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 |
--------------------------------------------------------------------------------
/ZZPhotoKitUITests/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 |
--------------------------------------------------------------------------------
/ZZPhotoKitUITests/ZZPhotoKitUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // ZZPhotoKitUITests.m
3 | // ZZPhotoKitUITests
4 | //
5 | // Created by Yuan on 16/1/4.
6 | // Copyright © 2016年 Ace. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ZZPhotoKitUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation ZZPhotoKitUITests
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 |
--------------------------------------------------------------------------------
/image/demonstrate.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/image/demonstrate.gif
--------------------------------------------------------------------------------
/image/examplepic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/image/examplepic.png
--------------------------------------------------------------------------------
/image/object.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/image/object.png
--------------------------------------------------------------------------------
/image/privacy_use.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/image/privacy_use.png
--------------------------------------------------------------------------------
/image/zz_camera_intro.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Glianze/ZZPhotoKit/bcb48e9983fa5458189ae6267eb018d554787301/image/zz_camera_intro.jpg
--------------------------------------------------------------------------------