Commit e69396e3194e1955a4342113964d82795bbf1ec9

Authored by 梁星国
1 parent 506347e9

提交创建

Showing 109 changed files with 1239 additions and 8995 deletions
.gitignore 0 → 100644
  1 +# OS X
  2 +.DS_Store
  3 +
  4 +# Xcode
  5 +build/
  6 +Products/
  7 +*.pbxuser
  8 +!default.pbxuser
  9 +*.mode1v3
  10 +!default.mode1v3
  11 +*.mode2v3
  12 +!default.mode2v3
  13 +*.perspectivev3
  14 +!default.perspectivev3
  15 +xcuserdata/
  16 +*.xccheckout
  17 +profile
  18 +*.moved-aside
  19 +DerivedData
  20 +*.hmap
  21 +*.ipa
  22 +
  23 +# Bundler
  24 +.bundle
  25 +
  26 +# Add this line if you want to avoid checking in source code from Carthage dependencies.
  27 +# Carthage/Checkouts
  28 +
  29 +Carthage/Build
  30 +
  31 +# We recommend against adding the Pods directory to your .gitignore. However
  32 +# you should judge for yourself, the pros and cons are mentioned at:
  33 +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
  34 +#
  35 +# Note: if you ignore the Pods directory, make sure to uncomment
  36 +# `pod install` in .travis.yml
  37 +#
  38 +# Pods/
... ...
CNLiveImagePickerController.podspec
1 1 #
2   -# Be sure to run `pod spec lint CNLiveImagePickerController.podspec' to ensure this is a
3   -# valid spec and to remove all comments including this before submitting the spec.
  2 +# Be sure to run `pod lib lint CNLiveImagePickerController.podspec' to ensure this is a
  3 +# valid spec before submitting.
4 4 #
5   -# To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
6   -# To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
  5 +# Any lines starting with a # are optional, but their use is encouraged
  6 +# To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
7 7 #
8 8  
9 9 Pod::Spec.new do |s|
10   -
11   -#
12   - # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
13   - #
14   - # These will help people to find your library, and whilst it
15   - # can feel like a chore to fill in it's definitely to your advantage. The
16   - # summary should be tweet-length, and the description more in depth.
17   - #
18   -
19   - s.name = "CNLiveImagePickerController" # 项目名称
20   - s.version = "0.0.2" # 版本号 与 你仓库的 标签号 对应
21   - s.summary = "相册选择基于TZImagePickerController" # 项目简介
22   -
23   - # This description is used to generate tags and improve search results.
24   - # * Think: What does it do? Why did you write it? What is the focus?
25   - # * Try to keep it short, snappy and to the point.
26   - # * Write the description between the DESC delimiters below.
27   - # * Finally, don't worry about the indent, CocoaPods strips it!
28   - s.description = <<-DESC
29   - 1.相册选择图片,视频
30   - 2.更改了相册适配问题
31   - DESC
32   -
33   - s.homepage = "http://bj.gitlab.cnlive.com/ios-team/CNLiveImagePickerController"
34   -
35   - # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
36   -
37   -
38   - # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
39   - #
40   - # Licensing your code is important. See http://choosealicense.com for more info.
41   - # CocoaPods will detect a license file if there is a named LICENSE*
42   - # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
43   - #
44   -
45   - s.license = "MIT" # 开源证书
46   - # s.license = { :type => "MIT", :file => "FILE_LICENSE" }
47   -
48   -
49   - # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
50   - #
51   - # Specify the authors of the library, with email addresses. Email addresses
52   - # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
53   - # accepts just a name if you'd rather not provide an email address.
54   - #
55   - # Specify a social_media_url where others can refer to, for example a twitter
56   - # profile URL.
57   - #
58   -
59   - s.author = { "梁星国" => "liangxingguo@cnlive.com" }
60   - # Or just: s.author = "梁星国"
61   - # s.authors = { "梁星国" => "jyyjkt@qq.com" }
62   - # s.social_media_url = "http://twitter.com/梁星国"
63   -
64   - # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
65   - #
66   - # If this Pod runs only on iOS or OS X, then specify the platform and
67   - # the deployment target. You can optionally include the target after the platform.
68   - #
69   -
70   - # s.platform = :ios
71   - s.platform = :ios, "9.0"
72   -
73   - # When using multiple platforms
74   - # s.ios.deployment_target = "5.0"
75   - # s.osx.deployment_target = "10.7"
76   - # s.watchos.deployment_target = "2.0"
77   - # s.tvos.deployment_target = "9.0"
78   -
79   -
80   - # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
81   - #
82   - # Specify the location from where the source should be retrieved.
83   - # Supports git, hg, bzr, svn and HTTP.
84   - #
85   -
86   - s.source = { :git => "http://bj.gitlab.cnlive.com/ios-team/CNLiveImagePickerController.git", :tag => "#{s.version}" } #你的仓库地址
87   -
88   -
89   - # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
90   - #
91   - # CocoaPods is smart about how it includes source code. For source files
92   - # giving a folder will include any swift, h, m, mm, c & cpp files.
93   - # For header files it will include any header in the folder.
94   - # Not including the public_header_files will make all headers public.
95   - #
96   -
97   - s.source_files = "CNLiveImagePickerController/*"
98   - s.exclude_files = "Classes/Exclude"
99   -
100   - # s.public_header_files = "Classes/**/*.h"
101   -
102   -
103   - # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
104   - #
105   - # A list of resources included with the Pod. These are copied into the
106   - # target bundle with a build phase script. Anything else will be cleaned.
107   - # You can preserve files from being cleaned, please don't preserve
108   - # non-essential files like tests, examples and documentation.
109   - #
110   -
111   - # s.resource = "icon.png"
112   - # s.resources = "Resources/*.png"
113   -
114   - # s.preserve_paths = "FilesToSave", "MoreFilesToSave"
115   -
116   -
117   - # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
118   - #
119   - # Link your library with frameworks, or libraries. Libraries do not include
120   - # the lib prefix of their name.
121   - #
122   -
123   - # s.framework = "SomeFramework"
124   - s.frameworks = "UIKit", "Foundation" #支持的框架
125   -
126   - # s.library = "iconv"
127   - # s.libraries = "iconv", "xml2"
128   -
129   -
130   - # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
131   - #
132   - # If your library depends on compiler flags you can set them in the xcconfig hash
133   - # where they will only apply to your library. If you depend on other Podspecs
134   - # you can include multiple dependencies to ensure it works.
135   -
136   - s.requires_arc = true
137   -
138   - # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
139   - # s.dependency "JSONKit", "~> 1.4"
140   -
  10 + s.name = 'CNLiveImagePickerController'
  11 + s.version = '0.1.0'
  12 + s.summary = 'A short description of CNLiveImagePickerController.'
  13 +
  14 +# This description is used to generate tags and improve search results.
  15 +# * Think: What does it do? Why did you write it? What is the focus?
  16 +# * Try to keep it short, snappy and to the point.
  17 +# * Write the description between the DESC delimiters below.
  18 +# * Finally, don't worry about the indent, CocoaPods strips it!
  19 +
  20 + s.description = <<-DESC
  21 +TODO: Add long description of the pod here.
  22 + DESC
  23 +
  24 + s.homepage = 'https://github.com/jyyjkt/CNLiveImagePickerController'
  25 + # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
  26 + s.license = { :type => 'MIT', :file => 'LICENSE' }
  27 + s.author = { 'jyyjkt' => 'jyyjkt@qq.com' }
  28 + s.source = { :git => 'https://github.com/jyyjkt/CNLiveImagePickerController.git', :tag => s.version.to_s }
  29 + # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'
  30 +
  31 + s.ios.deployment_target = '8.0'
  32 +
  33 + s.source_files = 'CNLiveImagePickerController/Classes/**/*'
  34 +
  35 + # s.resource_bundles = {
  36 + # 'CNLiveImagePickerController' => ['CNLiveImagePickerController/Assets/*.png']
  37 + # }
  38 +
  39 + # s.public_header_files = 'Pod/Classes/**/*.h'
  40 + # s.frameworks = 'UIKit', 'MapKit'
  41 + # s.dependency 'AFNetworking', '~> 2.3'
141 42 end
... ...
CNLiveImagePickerController/Assets/.gitkeep 0 → 100644
CNLiveImagePickerController/CNEditVideoController.h deleted 100755 → 0
1   -//
2   -// ZLEditVideoController.h
3   -// ZLPhotoBrowser
4   -//
5   -// Created by long on 2017/9/15.
6   -// Copyright © 2017年 long. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -@class TZAssetModel;
12   -
13   -@interface CNEditVideoController : UIViewController
14   -
15   -@property (nonatomic, strong) TZAssetModel *model;
16   -
17   -@property (nonatomic, strong) NSMutableArray *models; ///< All photo models / 所有图片模型数组
18   -@property (nonatomic, strong) NSMutableArray *photos; ///< All photos / 所有图片数组
19   -@property (nonatomic, assign) NSInteger currentIndex;
20   -@property (nonatomic, assign) BOOL isCropImage;
21   -
22   -/// Return the new selected photos / 返回最新的选中图片数组
23   -@property (nonatomic, copy) void (^backButtonEditClickBlock)(BOOL isSelectOriginalPhoto);
24   -@property (nonatomic, copy) void (^doneButtonEditClickBlock)(BOOL isSelectOriginalPhoto);
25   -
26   -
27   -@end
CNLiveImagePickerController/CNEditVideoController.m deleted 100755 → 0
1   -//
2   -// ZLEditVideoController.m
3   -// ZLPhotoBrowser
4   -//
5   -// Created by long on 2017/9/15.
6   -// Copyright © 2017年 long. All rights reserved.
7   -//
8   -
9   -#import "CNEditVideoController.h"
10   -#import <AVFoundation/AVFoundation.h>
11   -#import "TZAssetModel.h"
12   -#import <objc/runtime.h>
13   -#import <AssetsLibrary/AssetsLibrary.h>
14   -#import "TZImagePickerController.h"
15   -#import "TZPhotoPreviewCell.h"
16   -#import "TZImageCropManager.h"
17   -
18   -#define kItemWidth kItemHeight * 2/3
19   -#define kItemHeight 50
20   -#define kAPPName @"网++"
21   -
22   -#pragma mark - 显示帧数的CNEditFrameView
23   -
24   -@interface CNEditVideoCell : UICollectionViewCell
25   -
26   -@property (nonatomic, strong) UIImageView *imageView;
27   -
28   -@end
29   -
30   -@implementation CNEditVideoCell
31   -
32   -- (UIImageView *)imageView
33   -{
34   - if (!_imageView) {
35   - _imageView = [[UIImageView alloc] init];
36   - _imageView.frame = self.bounds;
37   - _imageView.contentMode = UIViewContentModeScaleAspectFill;
38   - _imageView.clipsToBounds = YES;
39   - [self.contentView addSubview:_imageView];
40   - }
41   - return _imageView;
42   -}
43   -
44   -@end
45   -
46   -#pragma mark - 协议编辑帧数协议CNEditFrameViewDelegate
47   -@protocol CNEditFrameViewDelegate <NSObject>
48   -
49   -- (void)editViewValidRectChanged;//有效范围更变
50   -
51   -- (void)editViewValidRectEndChanged;//有效范围更变结束
52   -
53   -@end
54   -
55   -#pragma mark - 编辑时视图CNEditFrameView
56   -@interface CNEditFrameView : UIView
57   -{
58   - UIImageView *_leftView;//左视图
59   - UIImageView *_rightView;//有视图
60   -}
61   -
62   -@property (nonatomic, assign) CGRect validRect;
63   -@property (nonatomic, weak) id<CNEditFrameViewDelegate> delegate;
64   -
65   -@end
66   -
67   -@implementation CNEditFrameView
68   -
69   -- (instancetype)init
70   -{
71   - self = [super init];
72   - if (self) {
73   - [self setupUI];
74   - }
75   - return self;
76   -}
77   -
78   -- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
79   -{
80   - //扩大下有效范围
81   - CGRect left = _leftView.frame;
82   - left.origin.x -= kItemWidth/2;
83   - left.size.width += kItemWidth/2;
84   - CGRect right = _rightView.frame;
85   - right.size.width += kItemWidth/2;
86   -
87   - if (CGRectContainsPoint(left, point)) {
88   - return _leftView;
89   - }
90   - if (CGRectContainsPoint(right, point)) {
91   - return _rightView;
92   - }
93   - return nil;
94   -}
95   -
96   -- (void)setupUI
97   -{
98   - self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:.5];
99   - self.layer.borderWidth = 2;
100   - self.layer.borderColor = [UIColor clearColor].CGColor;
101   -
102   - _leftView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"video_edit_left"]];
103   - _leftView.userInteractionEnabled = YES;
104   - _leftView.tag = 0;
105   - UIPanGestureRecognizer *lg = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
106   - [_leftView addGestureRecognizer:lg];
107   - [self addSubview:_leftView];
108   -
109   - _rightView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"video_edit_right"]];
110   - _rightView.userInteractionEnabled = YES;
111   - _rightView.tag = 1;
112   - UIPanGestureRecognizer *rg = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];
113   - [_rightView addGestureRecognizer:rg];
114   - [self addSubview:_rightView];
115   -}
116   -
117   -- (void)panAction:(UIGestureRecognizer *)pan //滑动收拾实现
118   -{
119   - self.layer.borderColor = [[UIColor whiteColor] colorWithAlphaComponent:.4].CGColor;
120   - CGPoint point = [pan locationInView:self];
121   -
122   - CGRect rct = self.validRect;
123   -
124   - const CGFloat W = self.frame.size.width;
125   - CGFloat minX = 0;
126   - CGFloat maxX = W;
127   -
128   - switch (pan.view.tag) {
129   - case 0: {
130   - //left视图响应
131   - maxX = rct.origin.x + rct.size.width - kItemWidth;
132   -
133   - point.x = MAX(minX, MIN(point.x, maxX));
134   - point.y = 0;
135   -
136   - rct.size.width -= (point.x - rct.origin.x);
137   - rct.origin.x = point.x;
138   - }
139   - break;
140   -
141   - case 1:
142   - {
143   - //right视图响应
144   - minX = rct.origin.x + kItemWidth/2;
145   - maxX = W - kItemWidth/2;
146   -
147   - point.x = MAX(minX, MIN(point.x, maxX));
148   - point.y = 0;
149   -
150   - rct.size.width = (point.x - rct.origin.x + kItemWidth/2);
151   - }
152   - break;
153   - }
154   -
155   - switch (pan.state) {
156   - case UIGestureRecognizerStateBegan:
157   - case UIGestureRecognizerStateChanged:
158   - if (self.delegate && [self.delegate respondsToSelector:@selector(editViewValidRectChanged)]) {
159   - [self.delegate editViewValidRectChanged];//滑动响应实现
160   - }
161   - break;
162   -
163   - case UIGestureRecognizerStateEnded:
164   - case UIGestureRecognizerStateCancelled:
165   - self.layer.borderColor = [UIColor clearColor].CGColor;
166   - if (self.delegate && [self.delegate respondsToSelector:@selector(editViewValidRectEndChanged)]) {
167   - [self.delegate editViewValidRectEndChanged];//滑动结束响应实现
168   - }
169   - break;
170   -
171   - default:
172   - break;
173   - }
174   -
175   -
176   - self.validRect = rct;
177   -}
178   -
179   -- (void)setValidRect:(CGRect)validRect//根据范围
180   -{
181   - _validRect = validRect;
182   - _leftView.frame = CGRectMake(validRect.origin.x - kItemWidth/4, 0, kItemWidth/2, kItemHeight);
183   - _rightView.frame = CGRectMake(validRect.origin.x+validRect.size.width-kItemWidth/4, 0, kItemWidth/2, kItemHeight);
184   -
185   - [self setNeedsDisplay];
186   -}
187   -
188   -- (void)drawRect:(CGRect)rect
189   -{
190   - CGContextRef context = UIGraphicsGetCurrentContext();
191   -
192   - CGContextClearRect(context, self.validRect);
193   -
194   - CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
195   - CGContextSetLineWidth(context, 4.0);
196   -
197   - CGPoint topPoints[2];
198   - topPoints[0] = CGPointMake(self.validRect.origin.x, 0);
199   - topPoints[1] = CGPointMake(self.validRect.origin.x+self.validRect.size.width, 0);
200   -
201   - CGPoint bottomPoints[2];
202   - bottomPoints[0] = CGPointMake(self.validRect.origin.x, kItemHeight);
203   - bottomPoints[1] = CGPointMake(self.validRect.origin.x+self.validRect.size.width, kItemHeight);
204   -
205   - CGContextAddLines(context, topPoints, 2);
206   - CGContextAddLines(context, bottomPoints, 2);
207   -
208   - CGContextDrawPath(context, kCGPathStroke);
209   -}
210   -
211   -@end
212   -
213   -
214   -#pragma mark - 编辑视频控制器CNEditVideoController
215   -@interface CNEditVideoController () <UIScrollViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate, CNEditFrameViewDelegate>
216   -{
217   - UIView *_bottomView;
218   - UIButton *_cancelBtn;
219   - UIButton *_doneBtn;
220   -
221   - NSTimer *_timer;
222   -
223   - //下方collectionview偏移量
224   - CGFloat _offsetX;
225   - BOOL _orientationChanged;
226   -
227   - UIView *_indicatorLine;
228   -
229   - AVAsset *_avAsset;
230   -
231   - NSTimeInterval _interval;
232   -
233   - NSInteger _measureCount;
234   - NSOperationQueue *_queue;
235   - NSMutableDictionary<NSString *, UIImage *> *_imageCache;
236   - NSMutableDictionary<NSString *, NSBlockOperation *> *_opCache;
237   -}
238   -
239   -@property (nonatomic, strong) AVPlayerLayer *playerLayer;
240   -@property (nonatomic, strong) UICollectionView *collectionView;
241   -@property (nonatomic, strong) CNEditFrameView *editView;
242   -@property (nonatomic, strong) AVAssetImageGenerator *generator;
243   -
244   -@end
245   -
246   -@implementation CNEditVideoController
247   -
248   -- (void)dealloc
249   -{
250   - [_queue cancelAllOperations];
251   - [self stopTimer];
252   - [[NSNotificationCenter defaultCenter] removeObserver:self];
253   -// NSLog(@"---- %s", __FUNCTION__);
254   -}
255   -
256   -- (AVAssetImageGenerator *)generator
257   -{
258   - if (!_generator) {
259   - _generator = [[AVAssetImageGenerator alloc] initWithAsset:_avAsset];
260   - _generator.maximumSize = CGSizeMake(kItemWidth*4, kItemHeight*4);
261   - _generator.appliesPreferredTrackTransform = YES;
262   - _generator.requestedTimeToleranceBefore = kCMTimeZero;
263   - _generator.requestedTimeToleranceAfter = kCMTimeZero;
264   - _generator.apertureMode = AVAssetImageGeneratorApertureModeProductionAperture;
265   - }
266   - return _generator;
267   -}
268   -
269   -- (void)viewDidLoad {
270   - [super viewDidLoad];
271   - [self setupUI];
272   - [self analysisAssetImages];
273   -
274   - _queue = [[NSOperationQueue alloc] init];
275   - _queue.maxConcurrentOperationCount = 3;
276   -
277   - _imageCache = [NSMutableDictionary dictionary];
278   - _opCache = [NSMutableDictionary dictionary];
279   -
280   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationChanged:) name:UIApplicationWillChangeStatusBarOrientationNotification object:nil];
281   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appResignActive) name:UIApplicationWillResignActiveNotification object:nil];
282   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
283   -}
284   -
285   -- (void)viewWillAppear:(BOOL)animated
286   -{
287   - [super viewWillAppear:animated];
288   - [UIApplication sharedApplication].statusBarHidden = YES;
289   - self.navigationController.navigationBar.hidden = YES;
290   -}
291   -
292   -- (void)viewWillDisappear:(BOOL)animated
293   -{
294   - [super viewWillDisappear:animated];
295   - self.navigationController.navigationBar.hidden = NO;
296   -}
297   -
298   -- (void)viewDidLayoutSubviews
299   -{
300   - [super viewDidLayoutSubviews];
301   -
302   - UIEdgeInsets inset = UIEdgeInsetsZero;
303   - if (@available(iOS 11, *)) {
304   - inset = self.view.safeAreaInsets;
305   - }
306   -
307   - self.playerLayer.frame = CGRectMake(15, inset.top>0?inset.top:30, [UIScreen mainScreen].bounds.size.width-30, [UIScreen mainScreen].bounds.size.height-160-inset.bottom);
308   -
309   - self.editView.frame = CGRectMake(([UIScreen mainScreen].bounds.size.width-kItemWidth*10)/2, [UIScreen mainScreen].bounds.size.height-100-inset.bottom, kItemWidth*10, kItemHeight);
310   - self.editView.validRect = self.editView.bounds;
311   - self.collectionView.frame = CGRectMake(inset.left, [UIScreen mainScreen].bounds.size.height-100-inset.bottom, [UIScreen mainScreen].bounds.size.width-inset.left-inset.right, kItemHeight);
312   -
313   - CGFloat leftOffset = (([UIScreen mainScreen].bounds.size.width-kItemWidth*10)/2-inset.left);
314   - CGFloat rightOffset = (([UIScreen mainScreen].bounds.size.width-kItemWidth*10)/2-inset.right);
315   - [self.collectionView setContentInset:UIEdgeInsetsMake(0, leftOffset, 0, rightOffset)];
316   - [self.collectionView setContentOffset:CGPointMake(_offsetX-leftOffset, 0)];
317   -
318   - CGFloat bottomViewH = 44;
319   - CGFloat bottomBtnH = 30;
320   - _bottomView.frame = CGRectMake(0, [UIScreen mainScreen].bounds.size.height-bottomViewH-inset.bottom, [UIScreen mainScreen].bounds.size.width, kItemHeight);
321   - _cancelBtn.frame = CGRectMake(10+inset.left, 7, 60, bottomBtnH);
322   - _doneBtn.frame = CGRectMake([UIScreen mainScreen].bounds.size.width-70-inset.right, 7, 60, bottomBtnH);
323   -
324   - [self.playerLayer setBackgroundColor:[UIColor clearColor].CGColor];
325   -}
326   -
327   -#pragma mark - notifies
328   -//设备旋转
329   -- (void)deviceOrientationChanged:(NSNotification *)notify
330   -{
331   - _offsetX = self.collectionView.contentOffset.x + self.collectionView.contentInset.left;
332   - _orientationChanged = YES;
333   -}
334   -
335   -- (void)appResignActive
336   -{
337   - [self stopTimer];
338   -}
339   -
340   -- (void)appBecomeActive
341   -{
342   - [self startTimer];
343   -}
344   -
345   -- (void)setupUI
346   -{
347   - //禁用返回手势
348   - if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
349   - self.navigationController.interactivePopGestureRecognizer.delegate = nil;
350   - self.navigationController.interactivePopGestureRecognizer.enabled = NO;
351   - }
352   -
353   - self.view.backgroundColor = [UIColor blackColor];
354   -
355   - self.playerLayer = [[AVPlayerLayer alloc] init];
356   - [self.view.layer addSublayer:self.playerLayer];
357   -
358   - UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
359   - layout.itemSize = CGSizeMake(kItemWidth, kItemHeight);
360   - layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
361   - layout.minimumInteritemSpacing = 0;
362   - layout.minimumLineSpacing = 0;
363   -
364   - self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
365   - self.collectionView.delegate = self;
366   - self.collectionView.dataSource = self;
367   - self.collectionView.backgroundColor = [UIColor clearColor];
368   - self.collectionView.showsHorizontalScrollIndicator = NO;
369   - [self.collectionView registerClass:CNEditVideoCell.class forCellWithReuseIdentifier:@"CNEditVideoCell"];
370   -
371   - [self.view addSubview:self.collectionView];
372   -
373   - [self creatBottomView];
374   -
375   - self.editView = [[CNEditFrameView alloc] init];
376   - self.editView.delegate = self;
377   - [self.view addSubview:self.editView];
378   -
379   - _indicatorLine = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 2, kItemHeight)];
380   -// _indicatorLine.backgroundColor = [RGBOF(0x0BBE06) colorWithAlphaComponent:.7];
381   -}
382   -
383   -- (void)creatBottomView
384   -{
385   - //下方视图
386   - _bottomView = [[UIView alloc] init];
387   - _bottomView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:.7];
388   - [self.view addSubview:_bottomView];
389   -
390   - _cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
391   - _cancelBtn.titleLabel.font = [UIFont systemFontOfSize:15];
392   - [_cancelBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
393   - [_cancelBtn setTitle:@"取消" forState:UIControlStateNormal];
394   - [_cancelBtn addTarget:self action:@selector(cancelBtn_click) forControlEvents:UIControlEventTouchUpInside];
395   - [_bottomView addSubview:_cancelBtn];
396   -
397   - _doneBtn = [UIButton buttonWithType:UIButtonTypeCustom];
398   - [_doneBtn setTitle:@"完成" forState:UIControlStateNormal];
399   - [_doneBtn setBackgroundColor:[UIColor clearColor]];
400   -// [_doneBtn setTitleColor:RGBOF(0x0BBE06) forState:UIControlStateNormal];
401   - _doneBtn.titleLabel.font = [UIFont systemFontOfSize:15];
402   - _doneBtn.layer.masksToBounds = YES;
403   - _doneBtn.layer.cornerRadius = 3.0f;
404   - [_doneBtn addTarget:self action:@selector(btnDone_click) forControlEvents:UIControlEventTouchUpInside];
405   - [_bottomView addSubview:_doneBtn];
406   -}
407   -
408   -#pragma mark - 解析视频每一帧图片
409   -- (void)analysisAssetImages
410   -{
411   - NSTimeInterval duration = 0.0;
412   - if ([self.model.asset isKindOfClass:[PHAsset class]]) {
413   - PHAsset *asset = self.model.asset;
414   - duration = asset.duration;
415   - }else if([self.model.asset isKindOfClass:[ALAsset class]]){
416   - duration = [[self.model.asset valueForProperty:ALAssetPropertyDuration] doubleValue];
417   - }
418   -
419   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
420   - _interval = _tzImagePickerVc.maxEditVideoTime/10.0;
421   - _measureCount = (NSInteger)(duration / _interval);
422   - ///播放视频的
423   - if ([self.model.asset isKindOfClass:[PHAsset class]]) {//PHAsset
424   - __weak typeof(self) weakSelf = self;
425   - [[PHCachingImageManager defaultManager] requestPlayerItemForVideo:self.model.asset options:nil resultHandler:^(AVPlayerItem * _Nullable playerItem, NSDictionary * _Nullable info) {
426   - dispatch_async(dispatch_get_main_queue(), ^{
427   - __strong typeof(weakSelf) strongSelf = weakSelf;
428   - if (!playerItem) return;
429   - AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
430   - strongSelf.playerLayer.player = player;
431   - [strongSelf startTimer];
432   - });
433   -
434   - }];
435   -
436   - ///截取视频帧数
437   - PHVideoRequestOptions* options = [[PHVideoRequestOptions alloc] init];
438   - options.version = PHVideoRequestOptionsVersionOriginal;
439   - options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
440   - options.networkAccessAllowed = YES;
441   - [[PHImageManager defaultManager] requestAVAssetForVideo:self.model.asset options:options resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
442   - __strong typeof(weakSelf) strongSelf = weakSelf;
443   - strongSelf->_avAsset = asset;
444   - dispatch_async(dispatch_get_main_queue(), ^{
445   - [strongSelf.collectionView reloadData];
446   - });
447   - }];
448   -
449   - }else if([self.model.asset isKindOfClass:[ALAsset class]]){//ALAsset
450   - ///播放视频的
451   - ALAsset *alAsset = (ALAsset *)self.model.asset;
452   - ALAssetRepresentation *defaultRepresentation = [alAsset defaultRepresentation];
453   - NSString *uti = [defaultRepresentation UTI];
454   - NSURL *videoURL = [[alAsset valueForProperty:ALAssetPropertyURLs] valueForKey:uti];
455   - AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:videoURL];
456   - AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
457   - self.playerLayer.player = player;
458   - [self startTimer];
459   -
460   - ///截取视频帧数
461   - NSURL *videoURL_al =[self.model.asset valueForProperty:ALAssetPropertyAssetURL]; // ALAssetPropertyURLs
462   - AVAsset *videoAsset = [AVURLAsset assetWithURL:videoURL];
463   - _avAsset = videoAsset ;
464   - [self.collectionView reloadData];
465   -
466   - }
467   -
468   -}
469   -
470   -#pragma mark - action
471   -- (void)cancelBtn_click
472   -{
473   - [self stopTimer];
474   -
475   - if (self.backButtonEditClickBlock) {
476   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
477   - self.backButtonEditClickBlock(_tzImagePickerVc.isSelectOriginalPhoto);
478   - }
479   - UIViewController *vc = [self.navigationController popViewControllerAnimated:NO];
480   - if (!vc) {
481   - [self dismissViewControllerAnimated:YES completion:nil];
482   - }
483   -}
484   -
485   -- (void)btnDone_click
486   -{
487   - [self stopTimer];
488   -
489   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
490   - [_tzImagePickerVc showProgressHUD];
491   -
492   - [self exportEditVideoForAsset:_avAsset range:[self getTimeRange] complete:^(BOOL isSuc, id asset) {
493   - [_tzImagePickerVc hideProgressHUD];
494   - if (isSuc) {
495   - TZAssetModel *editModel = [TZAssetModel modelWithAsset:asset type:TZAssetModelMediaTypeVideo];
496   -
497   - // 如果没有选中过照片 点击确定时选中当前预览的照片
498   - if (_tzImagePickerVc.selectedModels.count == 0 && _tzImagePickerVc.minImagesCount <= 0) {
499   - [_tzImagePickerVc addSelectedModel:editModel];
500   - }
501   -
502   - if (self.doneButtonEditClickBlock) {
503   - self.doneButtonEditClickBlock(_tzImagePickerVc.isSelectOriginalPhoto);
504   - }
505   - [_tzImagePickerVc hideProgressHUD];
506   - }else{
507   - [_tzImagePickerVc showAlertWithTitle:@"编辑失败"];
508   - }
509   -
510   - }];
511   -}
512   -#pragma mark - 截取视频
513   -
514   -- (void)exportEditVideoForAsset:(AVAsset *)asset range:(CMTimeRange)range complete:(void (^)(BOOL, id))complete
515   -{
516   - [self export:asset range:range presetName:AVAssetExportPresetPassthrough renderSize:CGSizeZero imageSize:CGSizeZero effectImage:nil birthRate:0 velocity:0 complete:^(NSString *exportFilePath, NSError *error) {
517   - if (!error) {
518   - [self saveVideoToAblum:[NSURL fileURLWithPath:exportFilePath] completion:^(BOOL isSuc, id asset) {
519   - dispatch_async(dispatch_get_main_queue(), ^{
520   - if (complete) complete(isSuc, asset);
521   - });
522   - }];
523   - } else {
524   - dispatch_async(dispatch_get_main_queue(), ^{
525   - if (complete) complete(NO, nil);
526   - });
527   - }
528   - }];
529   -}
530   -
531   -///保存视频到相册
532   -- (void)saveVideoToAblum:(NSURL *)url completion:(void (^)(BOOL, id))completion
533   -{
534   - if (iOS8Later) {
535   - PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
536   - if (status == PHAuthorizationStatusDenied) {
537   - if (completion) completion(NO, nil);
538   - } else if (status == PHAuthorizationStatusRestricted) {
539   - if (completion) completion(NO, nil);
540   - } else {
541   - __block PHObjectPlaceholder *placeholderAsset=nil;
542   - [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
543   - PHAssetChangeRequest *newAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:url];
544   - placeholderAsset = newAssetRequest.placeholderForCreatedAsset;
545   - } completionHandler:^(BOOL success, NSError * _Nullable error) {
546   - if (!success) {
547   - if (completion) completion(NO, nil);
548   - return;
549   - }
550   - PHAsset *asset = [self getAssetFromlocalIdentifier:placeholderAsset.localIdentifier];
551   - PHAssetCollection *desCollection = [self getDestinationCollection];
552   - if (!desCollection) completion(NO, nil);
553   -
554   - [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
555   - [[PHAssetCollectionChangeRequest changeRequestForAssetCollection:desCollection] addAssets:@[asset]];
556   - } completionHandler:^(BOOL success, NSError * _Nullable error) {
557   - if (completion) completion(success, asset);
558   - }];
559   - }];
560   - }
561   - }else{
562   -
563   - ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];
564   - [assetLibrary writeVideoAtPathToSavedPhotosAlbum:url completionBlock:^(NSURL *assetURL, NSError *error) {
565   - if (error) {
566   - NSLog(@"保存视频出错:%@",error.localizedDescription);
567   - if (completion) {
568   - completion(NO,nil);
569   - }
570   - } else {
571   - [assetLibrary assetForURL:assetURL resultBlock:^(ALAsset *asset) {
572   - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
573   - if (completion) {
574   - completion(YES,asset);
575   - }
576   - });
577   - } failureBlock:^(NSError *error) {
578   -
579   - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
580   - if (completion) {
581   - completion(NO,nil);
582   - }
583   - });
584   -
585   - }];
586   - }
587   - }];
588   -
589   - }
590   -
591   -}
592   -
593   -- (PHAsset *)getAssetFromlocalIdentifier:(NSString *)localIdentifier{
594   - if(localIdentifier == nil){
595   - NSLog(@"Cannot get asset from localID because it is nil");
596   - return nil;
597   - }
598   - PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil];
599   - if(result.count){
600   - return result[0];
601   - }
602   - return nil;
603   -}
604   -
605   -//获取自定义相册
606   -- (PHAssetCollection *)getDestinationCollection
607   -{
608   - //找是否已经创建自定义相册
609   - PHFetchResult<PHAssetCollection *> *collectionResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
610   - for (PHAssetCollection *collection in collectionResult) {
611   - if ([collection.localizedTitle isEqualToString:kAPPName]) {
612   - return collection;
613   - }
614   - }
615   - //新建自定义相册
616   - __block NSString *collectionId = nil;
617   - NSError *error = nil;
618   - [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{
619   - collectionId = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:kAPPName].placeholderForCreatedAssetCollection.localIdentifier;
620   - } error:&error];
621   - if (error) {
622   - return nil;
623   - }
624   - return [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[collectionId] options:nil].lastObject;
625   -}
626   -
627   -- (void)export:(AVAsset *)asset range:(CMTimeRange)range presetName:(NSString *)presetName renderSize:(CGSize)renderSize imageSize:(CGSize)imageSize effectImage:(UIImage *)effectImage birthRate:(NSInteger)birthRate velocity:(CGFloat)velocity complete:(void (^)(NSString *exportFilePath, NSError *error))complete
628   -{
629   - NSString *exportFilePath = [self getVideoExportFilePath];
630   -
631   - AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:presetName];
632   -
633   - NSURL *exportFileUrl = [NSURL fileURLWithPath:exportFilePath];
634   -
635   - exportSession.outputURL = exportFileUrl;
636   - exportSession.outputFileType = AVFileTypeMPEG4;
637   - exportSession.timeRange = range;
638   - // exportSession.shouldOptimizeForNetworkUse = YES;
639   - if (!CGSizeEqualToSize(renderSize, CGSizeZero)) {
640   - AVMutableVideoComposition *com = [self getVideoComposition:asset renderSize:renderSize imageSize:imageSize effectImage:effectImage birthRate:birthRate velocity:velocity];
641   - if (!com) {
642   - if (complete) {
643   - complete(nil, [NSError errorWithDomain:@"视频裁剪导出失败" code:-1 userInfo:@{@"message": @"视频对象格式可能有错误,没有检测到视频通道"}]);
644   - }
645   - return;
646   - }
647   - exportSession.videoComposition = com;
648   - }
649   -
650   - [exportSession exportAsynchronouslyWithCompletionHandler:^{
651   - BOOL suc = NO;
652   - switch ([exportSession status]) {
653   - case AVAssetExportSessionStatusFailed:
654   - NSLog(@"Export failed: %@", [[exportSession error] localizedDescription]);
655   - break;
656   - case AVAssetExportSessionStatusCancelled:
657   - NSLog(@"Export canceled");
658   - break;
659   -
660   - case AVAssetExportSessionStatusCompleted:{
661   - NSLog(@"Export completed");
662   - suc = YES;
663   - }
664   - break;
665   -
666   - default:
667   - NSLog(@"Export other");
668   - break;
669   - }
670   -
671   - if (complete) {
672   - complete(suc?exportFilePath:nil, suc?nil:exportSession.error);
673   - if (!suc) {
674   - [exportSession cancelExport];
675   - }
676   - }
677   - }];
678   -}
679   -
680   -- (NSString *)getVideoExportFilePath
681   -{
682   - NSString *format = @"mp4";
683   -
684   - NSString *exportFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", [self getUniqueStrByUUID], format]];
685   -
686   - return exportFilePath;
687   -}
688   -
689   -- (NSString *)getUniqueStrByUUID
690   -{
691   - CFUUIDRef uuidObj = CFUUIDCreate(nil);//create a new UUID
692   -
693   - //get the string representation of the UUID
694   - CFStringRef uuidString = CFUUIDCreateString(nil, uuidObj);
695   -
696   - NSString *str = [NSString stringWithString:(__bridge NSString *)uuidString];
697   -
698   - CFRelease(uuidObj);
699   - CFRelease(uuidString);
700   -
701   - return [str lowercaseString];
702   -}
703   -
704   -
705   -- (AVMutableVideoComposition *)getVideoComposition:(AVAsset *)asset renderSize:(CGSize)renderSize imageSize:(CGSize)imageSize effectImage:(UIImage *)effectImage birthRate:(NSInteger)birthRate velocity:(CGFloat)velocity
706   -{
707   - AVMutableComposition *composition = [AVMutableComposition composition];
708   - //视频通道
709   - AVMutableCompositionTrack *assetVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
710   - //音频通道
711   - AVMutableCompositionTrack *assetAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
712   -
713   - NSError *error = nil;
714   - //裁剪时长
715   - CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, asset.duration);
716   -
717   - AVAssetTrack *videoTrack = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;//视频
718   - AVAssetTrack *audioTrack = [asset tracksWithMediaType:AVMediaTypeAudio].firstObject;//音频
719   -
720   - if (!videoTrack) {
721   - return nil;
722   - }
723   - [assetVideoTrack insertTimeRange:timeRange ofTrack:videoTrack atTime:kCMTimeZero error:&error];
724   - NSLog(@"%@", error);
725   - if (audioTrack) {
726   - [assetAudioTrack insertTimeRange:timeRange ofTrack:audioTrack atTime:kCMTimeZero error:&error];
727   - NSLog(@"%@", error);
728   - }
729   -
730   - if (error) {
731   - return nil;
732   - }
733   -
734   - AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
735   - instruction.timeRange = CMTimeRangeMake(kCMTimeZero, composition.duration);
736   -
737   - //处理视频旋转
738   - AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:assetVideoTrack];
739   - [layerInstruction setOpacity:0.0 atTime:assetVideoTrack.timeRange.duration];
740   - //视频旋转,获取视频旋转角度,然后旋转对应角度,保持视频方向正确
741   - CGFloat degree = [self getVideoDegree:videoTrack];
742   - CGSize naturalSize = assetVideoTrack.naturalSize;
743   -
744   - CGAffineTransform mixedTransform = CGAffineTransformIdentity;
745   - //处理renderSize,不能大于视频宽高
746   - CGFloat videoWidth = (degree==0 || degree==M_PI) ? naturalSize.width : naturalSize.height;
747   - CGFloat videoHeight = (degree==0 || degree==M_PI) ? naturalSize.height : naturalSize.width;
748   - CGSize cropSize = CGSizeMake(MIN(videoWidth, renderSize.width), MIN(videoHeight, renderSize.height));
749   - CGFloat x, y;
750   - if (degree == M_PI_2) {
751   - //顺时针 90°
752   - CGAffineTransform t = CGAffineTransformMakeTranslation(naturalSize.height,.0);
753   - CGAffineTransform t1 = CGAffineTransformRotate(t, M_PI_2);
754   - //x为正向下 y为正向左
755   - x = -(videoHeight-cropSize.height)/2;
756   - y = (videoWidth-cropSize.width)/2;
757   - mixedTransform = CGAffineTransformTranslate(t1, x, y);
758   - } else if (degree == M_PI) {
759   - //顺时针 180°
760   - CGAffineTransform t = CGAffineTransformMakeTranslation(naturalSize.width, naturalSize.height);
761   - CGAffineTransform t1 = CGAffineTransformRotate(t, M_PI);
762   - //x为正向左 y为正向上
763   - x = (videoWidth-cropSize.width)/2;
764   - y = (videoHeight-cropSize.height)/2;
765   - mixedTransform = CGAffineTransformTranslate(t1, x, y);
766   - } else if (degree == (M_PI_2 * 3)) {
767   - //顺时针 270°
768   - CGAffineTransform t = CGAffineTransformMakeTranslation(.0, naturalSize.width);
769   - CGAffineTransform t1 = CGAffineTransformRotate(t, M_PI_2*3);
770   - //x为正向上 y为正向右
771   - x = (videoHeight-cropSize.height)/2;
772   - y = -(videoWidth-cropSize.width)/2;
773   - mixedTransform = CGAffineTransformTranslate(t1, x, y);
774   - } else {
775   - //x为正向右 y为正向下
776   - x = -(videoWidth-cropSize.width)/2;
777   - y = -(videoHeight-cropSize.height)/2;
778   - mixedTransform = CGAffineTransformMakeTranslation(x, y);
779   - }
780   -
781   - [layerInstruction setTransform:mixedTransform atTime:kCMTimeZero];
782   -
783   - //管理所有需要处理的视频
784   - AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
785   - videoComposition.frameDuration = CMTimeMake(1, 30);
786   - videoComposition.renderScale = 1;
787   - videoComposition.renderSize = cropSize;
788   -
789   - instruction.layerInstructions = @[layerInstruction];
790   - videoComposition.instructions = @[instruction];
791   -
792   - return videoComposition;
793   -}
794   -
795   -- (CGFloat)getVideoDegree:(AVAssetTrack *)videoTrack
796   -{
797   - CGAffineTransform tf = videoTrack.preferredTransform;
798   -
799   - CGFloat degree = 0;
800   - if (tf.b == 1.0 && tf.c == -1.0) {
801   - degree = M_PI_2;
802   - } else if (tf.a == -1.0 && tf.d == -1.0) {
803   - degree = M_PI;
804   - } else if (tf.b == -1.0 && tf.c == 1.0) {
805   - degree = M_PI_2 * 3;
806   - }
807   - return degree;
808   -}
809   -
810   -
811   -
812   -#pragma mark - timer
813   -- (void)startTimer
814   -{
815   - [self stopTimer];
816   -
817   - CGFloat duration = _interval * self.editView.validRect.size.width / (kItemWidth);
818   - _timer = [NSTimer scheduledTimerWithTimeInterval:duration target:self selector:@selector(playPartVideo:) userInfo:nil repeats:YES];
819   - [_timer fire];
820   - [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
821   -
822   - _indicatorLine.frame = CGRectMake(self.editView.validRect.origin.x, 0, 4, kItemHeight);
823   - [self.editView addSubview:_indicatorLine];
824   - [UIView animateWithDuration:duration delay:.0 options:UIViewAnimationOptionRepeat|UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionCurveLinear animations:^{
825   - _indicatorLine.frame = CGRectMake(CGRectGetMaxX(self.editView.validRect)-2, 0, 2, kItemHeight);
826   - } completion:nil];
827   -}
828   -
829   -- (void)stopTimer
830   -{
831   - [_timer invalidate];
832   - _timer = nil;
833   - [_indicatorLine removeFromSuperview];
834   - [self.playerLayer.player pause];
835   -}
836   -
837   -- (CMTime)getStartTime
838   -{
839   - CGRect rect = [self.collectionView convertRect:self.editView.validRect fromView:self.editView];
840   - CGFloat s = MAX(0, _interval * rect.origin.x / (kItemWidth));
841   - return CMTimeMakeWithSeconds(s, self.playerLayer.player.currentTime.timescale);
842   -}
843   -
844   -- (CMTimeRange)getTimeRange
845   -{
846   - CMTime start = [self getStartTime];
847   - CGFloat d = _interval * self.editView.validRect.size.width / (kItemWidth);
848   - CMTime duration = CMTimeMakeWithSeconds(d, self.playerLayer.player.currentTime.timescale);
849   - return CMTimeRangeMake(start, duration);
850   -}
851   -
852   -- (void)playPartVideo:(NSTimer *)timer
853   -{
854   - [self.playerLayer.player play];
855   - [self.playerLayer.player seekToTime:[self getStartTime] toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
856   -}
857   -
858   -#pragma mark - edit view delegate
859   -- (void)editViewValidRectChanged
860   -{
861   - [self stopTimer];
862   - [self.playerLayer.player seekToTime:[self getStartTime] toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
863   -}
864   -
865   -- (void)editViewValidRectEndChanged
866   -{
867   - [self startTimer];
868   -}
869   -
870   -#pragma mark - scroll view delegate
871   -- (void)scrollViewDidScroll:(UIScrollView *)scrollView
872   -{
873   - if (!self.playerLayer.player || _orientationChanged) {
874   - _orientationChanged = NO;
875   - return;
876   - }
877   - [self stopTimer];
878   - [self.playerLayer.player seekToTime:[self getStartTime] toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
879   -}
880   -
881   -- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
882   -{
883   - if (!decelerate) {
884   - [self startTimer];
885   - }
886   -}
887   -
888   -- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
889   -{
890   - [self startTimer];
891   -}
892   -
893   -#pragma mark - collection view data sources
894   -- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
895   -{
896   - return _measureCount;
897   -}
898   -
899   -- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
900   -{
901   - CNEditVideoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CNEditVideoCell" forIndexPath:indexPath];
902   -
903   - UIImage *image = _imageCache[@(indexPath.row).stringValue];
904   - if (image) {
905   - cell.imageView.image = image;
906   - }
907   -
908   - return cell;
909   -}
910   -
911   -static const char _CNOperationCellKey;
912   -- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
913   -{
914   - if (!_avAsset) return;
915   -
916   - if (_imageCache[@(indexPath.row).stringValue] || _opCache[@(indexPath.row).stringValue]) {
917   - return;
918   - }
919   -
920   - NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
921   - NSInteger row = indexPath.row;
922   - NSInteger i = row * _interval;
923   -
924   - CMTime time = CMTimeMake((i+0.35) * _avAsset.duration.timescale, _avAsset.duration.timescale);
925   -
926   - NSError *error = nil;
927   - CGImageRef cgImg = [self.generator copyCGImageAtTime:time actualTime:NULL error:&error];
928   - if (!error && cgImg) {
929   - UIImage *image = [UIImage imageWithCGImage:cgImg];
930   - CGImageRelease(cgImg);
931   -
932   - [_imageCache setValue:image forKey:@(row).stringValue];
933   -
934   - dispatch_async(dispatch_get_main_queue(), ^{
935   -
936   - NSIndexPath *nowIndexPath = [collectionView indexPathForCell:cell];
937   - if (row == nowIndexPath.row) {
938   - [(CNEditVideoCell *)cell imageView].image = image;
939   - } else {
940   - UIImage *cacheImage = _imageCache[@(nowIndexPath.row).stringValue];
941   - if (cacheImage) {
942   - [(CNEditVideoCell *)cell imageView].image = cacheImage;
943   - }
944   - }
945   - });
946   - [_opCache removeObjectForKey:@(row).stringValue];
947   - }
948   - objc_removeAssociatedObjects(cell);
949   - }];
950   - [_queue addOperation:op];
951   - [_opCache setValue:op forKey:@(indexPath.row).stringValue];
952   -
953   - objc_setAssociatedObject(cell, &_CNOperationCellKey, op, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
954   -}
955   -
956   -- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
957   -{
958   - NSBlockOperation *op = objc_getAssociatedObject(cell, &_CNOperationCellKey);
959   - if (op) {
960   - [op cancel];
961   - objc_removeAssociatedObjects(cell);
962   - [_opCache removeObjectForKey:@(indexPath.row).stringValue];
963   - }
964   -}
965   -
966   -- (void)didReceiveMemoryWarning {
967   - [super didReceiveMemoryWarning];
968   - // Dispose of any resources that can be recreated.
969   -}
970   -
971   -/*
972   -#pragma mark - Navigation
973   -
974   -// In a storyboard-based application, you will often want to do a little preparation before navigation
975   -- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
976   - // Get the new view controller using [segue destinationViewController].
977   - // Pass the selected object to the new view controller.
978   -}
979   -*/
980   -
981   -@end
CNLiveImagePickerController/CNImagePickerCommonDefine.h deleted 100644 → 0
1   -//
2   -// CNImagePickerCommonDefine.h
3   -// CNLiveImagePickerControllerExample
4   -//
5   -// Created by 梁星国 on 2018/10/25.
6   -// Copyright © 2018年 梁星国. All rights reserved.
7   -//
8   -
9   -#ifndef CNImagePickerCommonDefine_h
10   -#define CNImagePickerCommonDefine_h
11   -
12   -
13   -////////////////////////////////////////////////////////
14   -//////////// Color
15   -////////////////////////////////////////////////////////
16   -
17   -#define IP_RGBOF(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \
18   -green:((float)((rgbValue & 0xFF00) >> 8))/255.0 \
19   -blue:((float)(rgbValue & 0xFF))/255.0 \
20   -alpha:1.0]
21   -
22   -#define IP_RGBA_OF(rgbValue) [UIColor colorWithRed:((float)(((rgbValue) & 0xFF000000) >> 24))/255.0 \
23   -green:((float)(((rgbValue) & 0x00FF0000) >> 16))/255.0 \
24   -blue:((float)(rgbValue & 0x0000FF00) >> 8)/255.0 \
25   -alpha:((float)(rgbValue & 0x000000FF))/255.0]
26   -
27   -#define IP_RGBAOF(v, a) [UIColor colorWithRed:((float)(((v) & 0xFF0000) >> 16))/255.0 \
28   -green:((float)(((v) & 0x00FF00) >> 8))/255.0 \
29   -blue:((float)(v & 0x0000FF))/255.0 \
30   -alpha:a]
31   -
32   -
33   -////////////////////////////////////////////////////////
34   -//////////// 发送图片,视频限制
35   -////////////////////////////////////////////////////////
36   -#define kFriendsCircle_limit_photo 20*1024.0*1024.0 //朋友圈限制图片20M
37   -#define kFirendsCircle_limit_video 30*1024.0*1024.0 //朋友圈限制视频30M
38   -#define kTarentoComment_limit_photo 10*1024.0*1024.0 //达人评论10M
39   -#define kSweepCode_limit_phoho 10*1024.0*1024.0 //扫码10M限制
40   -#define kChat_limit_photo 20*1024.0*1024.0 //聊天限制图片20M
41   -#define kChat_limit_video 20*1024.0*1024.0 //聊天限制视频20M
42   -
43   -#define kChat_limit_video_length 5*60 //聊天限制视频5分钟
44   -#define kFriendsCircle_limit_video_maxEdit 5*60 //朋友圈限制视频5分钟
45   -#define kFriendsCircle_limit_video_max 10*60 //朋友圈限制最大视频编辑10分钟
46   -
47   -
48   -
49   -////////////////////////////////////////////////////////
50   -//////////// SCreen
51   -////////////////////////////////////////////////////////
52   -#define kIPScreenWidth ([UIScreen mainScreen].bounds.size.width > [UIScreen mainScreen].bounds.size.height ? [UIScreen mainScreen].bounds.size.height : [UIScreen mainScreen].bounds.size.width)
53   -#define kIPScreenHeight ([UIScreen mainScreen].bounds.size.width > [UIScreen mainScreen].bounds.size.height ? [UIScreen mainScreen].bounds.size.width : [UIScreen mainScreen].bounds.size.height)
54   -
55   -
56   -//判断iPHoneXr
57   -#define IP_Device_Is_iPhoneXS_XR ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(828, 1792), [[UIScreen mainScreen] currentMode].size) : NO)
58   -
59   -//判断iPHoneX、iPHoneXs
60   -#define IP_Device_Is_iPhoneX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)
61   -#define IP_Device_Is_iPhoneXS ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1125, 2436), [[UIScreen mainScreen] currentMode].size) : NO)
62   -
63   -//判断iPhoneXs Max
64   -#define IP_Device_Is_iPhoneXS_MAX ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(1242, 2688), [[UIScreen mainScreen] currentMode].size) : NO)
65   -
66   -#define IP_IS_IPhoneX_All (CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(375, 812)) ||CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(812, 375)) ||CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(414, 896)) ||CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(896, 414)))
67   -
68   -
69   -#define kIPStatusHeight (int)[UIApplication sharedApplication].statusBarFrame.size.height //x44 非x20
70   -#define kIPNavigationBarHeight ((int)[UIApplication sharedApplication].statusBarFrame.size.height+44) //x88 非x64
71   -#define kIPVerticalNaviBarHeight ((IP_IS_IPhoneX_All > 0) ? 88 : 44)
72   -#define kIPVerticalTabBarTotalHeight ((IP_IS_IPhoneX_All > 0) ? 83 : 49)
73   -#define kIPVerticalBottomSafeHeight ((IP_IS_IPhoneX_All > 0) ? 34 : 0)
74   -#define kIPVerticalStatusHeight ((IP_IS_IPhoneX_All > 0) ? 44 : 20)
75   -#define kIPVerticalTopHeight ((IP_IS_IPhoneX_All > 0) ? 24 : 0)
76   -#define kIPHorizontalTopNaviBarHeight 32
77   -#define kIPHorizontalBottomHeight ((IP_IS_IPhoneX_All > 0) ? 21 : 0)
78   -#define kIPHorizontalLeftHeight ((IP_IS_IPhoneX_All > 0) ? 44 : 0)
79   -#define kIPHorizontalRightHeight ((IP_IS_IPhoneX_All > 0) ? 44 : 0)
80   -#define kIPHorizontalTopHeight ((IP_IS_IPhoneX_All > 0) ? 24 : 0)
81   -
82   -#endif /* CNImagePickerCommonDefine_h */
CNLiveImagePickerController/CNImagePickerController.h deleted 100644 → 0
1   -//
2   -// CNTZImagePickerControllerViewController.h
3   -// CNLiveNetAdd
4   -//
5   -// Created by 梁星国 on 2018/8/22.
6   -// Copyright © 2018年 cnlive. All rights reserved.
7   -//
8   -
9   -#import "TZImagePickerController.h"
10   -
11   -@interface CNImagePickerController : TZImagePickerController
12   -
13   -/**
14   - 配置
15   - */
16   -- (void)configTZImagePicker;
17   -
18   -@end
CNLiveImagePickerController/CNImagePickerController.m deleted 100644 → 0
1   -//
2   -// CNTZImagePickerControllerViewController.m
3   -// CNLiveNetAdd
4   -//
5   -// Created by 梁星国 on 2018/8/22.
6   -// Copyright © 2018年 cnlive. All rights reserved.
7   -//
8   -
9   -#import "CNImagePickerController.h"
10   -#import "CNImagePickerCommonDefine.h"
11   -#import "UIImage+CNImagePicker.h"
12   -
13   -@interface CNImagePickerController ()
14   -
15   -@end
16   -
17   -@implementation CNImagePickerController
18   -
19   -- (void)viewDidLoad {
20   - [super viewDidLoad];
21   -
22   -}
23   -
24   -/**
25   - 配置 详情看TZImagePickerController
26   - */
27   -- (void)configTZImagePicker{
28   -
29   -#pragma mark - 五类个性化设置,这些参数都可以不传,此时会走默认设置
30   - // 1.设置目前已经选中的图片数组
31   - self.allowTakePicture = NO; // 在内部显示拍照按钮
32   - self.allowTakeVideo = NO;// 在内部拍摄按钮
33   - self.videoMaximumDuration = 10; // 视频最大拍摄时间
34   - [self setUiImagePickerControllerSettingBlock:^(UIImagePickerController *imagePickerController) {
35   - imagePickerController.videoQuality = UIImagePickerControllerQualityTypeHigh;//拍摄分辨率
36   - }];
37   - self.iconThemeColor = IP_RGBOF(0x00BBE06);// 主体颜色
38   - self.showPhotoCannotSelectLayer = YES;//达到上限是否有浮层
39   - self.cannotSelectLayerColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8];//设置达到上限的浮层
40   -
41   - self.photoDefImage = [UIImage imageNamedFromMyBundle:@"photo_cell_normal"];
42   - self.photoSelImage = [UIImage ip_imageWithColor:IP_RGBOF(0x0BBE06) size:CGSizeMake(22, 22) radius:11];
43   - self.photoOriginDefImage = [UIImage imageNamedFromMyBundle:@"photo_original_nor"];
44   -
45   - // 3. 设置是否可以选择视频/图片/原图/gif
46   - self.allowPickingVideo = YES;// 显示视频
47   - self.allowPickingImage = YES;// 显示图片
48   - self.allowPickingOriginalPhoto = YES; //显示原图
49   - self.allowPickingGif = NO;// 显示GIF
50   - self.allowPickingMultipleVideo = YES; // 是否可以多选视频
51   -
52   - // 4. 照片排列按修改时间升序
53   - self.sortAscendingByModificationDate = YES;
54   -
55   - // imagePickerVc.minImagesCount = 3;
56   - // imagePickerVc.alwaysEnableDoneBtn = YES;
57   -
58   - // imagePickerVc.minPhotoWidthSelectable = 3000;
59   - // imagePickerVc.minPhotoHeightSelectable = 2000;
60   -
61   - /// 5. Single selection mode, valid when maxImagesCount = 1
62   - /// 5. 单选模式,maxImagesCount为1时才生效
63   - self.showSelectBtn = NO;
64   - self.allowCrop = NO;
65   - self.needCircleCrop = NO;
66   - // 设置横屏下的裁剪尺寸
67   - // imagePickerVc.cropRectLandscape = CGRectMake((self.view.tz_height - widthHeight) / 2, left, widthHeight, widthHeight);
68   - /*
69   - [imagePickerVc setCropViewSettingBlock:^(UIView *cropView) {
70   - cropView.layer.borderColor = [UIColor redColor].CGColor;
71   - cropView.layer.borderWidth = 2.0;
72   - }];*/
73   -
74   - //imagePickerVc.allowPreview = NO;
75   - // 自定义导航栏上的返回按钮
76   - /*
77   - [imagePickerVc setNavLeftBarButtonSettingBlock:^(UIButton *leftButton){
78   - [leftButton setImage:[UIImage imageNamed:@"back"] forState:UIControlStateNormal];
79   - [leftButton setImageEdgeInsets:UIEdgeInsetsMake(0, -10, 0, 20)];
80   - }];
81   - imagePickerVc.delegate = self;
82   - */
83   -
84   - self.statusBarStyle = UIStatusBarStyleDefault;//状态栏黑色
85   -
86   - self.showSelectedIndex = YES; // 设置是否显示图片序号
87   -
88   - self.naviBgColor = IP_RGBOF(0xFFFFFF);//导航栏颜色
89   - self.naviTitleColor = IP_RGBOF(0x282828);//相册title
90   - self.naviTitleFont = [UIFont systemFontOfSize:18];//title文字大小
91   - [self setNavLeftBarButtonSettingBlock:^(UIButton *leftButton) {//设置返回按钮图标
92   - [leftButton setImage:[UIImage imageNamedFromMyBundle:@"photoback"] forState:UIControlStateNormal];//返回按钮图片
93   - [leftButton setTitle:@"返回" forState:UIControlStateNormal];//设置文字大小
94   - [leftButton setTitleColor:IP_RGBOF(0x282828) forState:UIControlStateNormal];//设置文字颜色
95   - leftButton.titleLabel.font = [UIFont systemFontOfSize:15];//设置文字大小
96   - leftButton.imageEdgeInsets = UIEdgeInsetsMake(0, -7, 0, +7);//设置图片边缘
97   - }];
98   - self.barItemTextColor = IP_RGBOF(0x282828);//设置barItem文字颜色
99   - self.barItemTextFont = [UIFont systemFontOfSize:15];
100   -
101   - // 设置首选语言 / Set preferred language
102   - // imagePickerVc.preferredLanguage = @"zh-Hans";
103   -
104   - // 设置languageBundle以使用其它语言 / Set languageBundle to use other language
105   - // imagePickerVc.languageBundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"tz-ru" ofType:@"lproj"]];
106   -
107   - /// 【自定义各页面/组件的样式】在界面初始化/组件setModel完成后调用,允许外界修改样式等
108   - //相册
109   - [self setPhotoPickerPageUIConfigBlock:^(UICollectionView *collectionView, UIView *bottomToolBar, UIButton *previewButton, UIButton *originalPhotoButton, UILabel *originalPhotoLabel, UIButton *doneButton, UIImageView *numberImageView, UILabel *numberLabel, UIView *divideLine) {
110   -
111   - //底部栏
112   - [bottomToolBar setBackgroundColor:IP_RGBOF(0xFFFFFF)];
113   -
114   - //预览
115   - previewButton.titleLabel.font = [UIFont systemFontOfSize:16];
116   - [previewButton setTitleColor:IP_RGBOF(0xB3B3B3) forState:UIControlStateDisabled];//禁用
117   - [previewButton setTitleColor:IP_RGBOF(0x000000) forState:UIControlStateNormal];//默认
118   -
119   - //原图按钮
120   - [originalPhotoButton setImage:[UIImage imageNamedFromMyBundle:@"photo_original_normal"] forState:UIControlStateDisabled];//禁用
121   - [originalPhotoButton setImage:[UIImage imageNamedFromMyBundle:@"photo_original_normal"] forState:UIControlStateNormal];//默认
122   - [originalPhotoButton setImage:[UIImage imageNamedFromMyBundle:@"photo_original_select"] forState:UIControlStateSelected];//选中
123   - originalPhotoButton.titleLabel.font = [UIFont systemFontOfSize:16];
124   - [originalPhotoButton setTitleColor:IP_RGBOF(0xB3B3B3) forState:UIControlStateDisabled];
125   - [originalPhotoButton setTitleColor:IP_RGBOF(0x000000) forState:UIControlStateNormal];
126   -
127   - //原图文字提示
128   - originalPhotoLabel.font = [UIFont systemFontOfSize:16];
129   - originalPhotoLabel.textColor = IP_RGBOF(0xB3B3B3);
130   - originalPhotoLabel.hidden = YES;
131   -
132   - //选中提示
133   - numberImageView = [UIImageView new];
134   - numberLabel = [UILabel new];
135   -
136   - //完成按钮
137   - doneButton.titleLabel.font = [UIFont systemFontOfSize:13];
138   - [doneButton setTitle:@"完成" forState:UIControlStateDisabled];
139   - [doneButton setTitleColor:IP_RGBAOF(0xFFFFFF, 0.5) forState:UIControlStateDisabled];
140   - [doneButton setTitleColor:IP_RGBOF(0xFFFFFF) forState:UIControlStateNormal];
141   -
142   - //颜色绘制成图片
143   - UIImage *dis_image = [UIImage ip_imageWithColor:IP_RGBAOF(0x0BBE06, 0.5)];
144   - [doneButton setBackgroundImage:dis_image forState:UIControlStateDisabled];
145   - UIImage *nor_image = [UIImage ip_imageWithColor:IP_RGBOF(0x0BBE06)];
146   - [doneButton setBackgroundImage:nor_image forState:UIControlStateNormal];
147   - doneButton.layer.masksToBounds = YES;
148   - doneButton.layer.cornerRadius = 5;
149   -
150   - //分割线
151   - [divideLine setBackgroundColor:IP_RGBOF(0xDEDEDE)];
152   -
153   - }];
154   -
155   - //图片预览
156   - [self setPhotoPreviewPageUIConfigBlock:^(UICollectionView *collectionView, UIView *naviBar, UIButton *backButton, UIButton *selectButton, UILabel *indexLabel, UIView *toolBar, UIButton *originalPhotoButton, UILabel *originalPhotoLabel, UIButton *doneButton, UIImageView *numberImageView, UILabel *numberLabel) {
157   -
158   - //返回按钮
159   - [backButton setImage:[UIImage imageNamedFromMyBundle:@"photo_original_back"] forState:UIControlStateNormal];
160   - //选择按钮
161   - [selectButton setImage:[UIImage imageNamedFromMyBundle:@"photo_original_nor"] forState:UIControlStateNormal];
162   - [selectButton setImage:[UIImage ip_imageWithColor:IP_RGBOF(0x0BBE06) size:CGSizeMake(28, 28) radius:14] forState:UIControlStateSelected];
163   - [selectButton setTitle:@"" forState:UIControlStateDisabled];
164   -
165   - //原图按钮
166   - [originalPhotoButton setImage:[UIImage imageNamedFromMyBundle:@"photo_original_normal"] forState:UIControlStateDisabled];//禁用
167   - [originalPhotoButton setImage:[UIImage imageNamedFromMyBundle:@"photo_original_normal"] forState:UIControlStateNormal];//默认
168   - [originalPhotoButton setImage:[UIImage imageNamedFromMyBundle:@"photo_original_select"] forState:UIControlStateSelected];//选中
169   - originalPhotoButton.titleLabel.font = [UIFont systemFontOfSize:16];
170   - [originalPhotoButton setTitleColor:IP_RGBOF(0xB3B3B3) forState:UIControlStateDisabled];
171   - [originalPhotoButton setTitleColor:IP_RGBAOF(0xFFFFFF, 0.7) forState:UIControlStateNormal];
172   - //原图内容隐藏
173   - originalPhotoLabel.hidden = YES;
174   -
175   - //完成按钮
176   - doneButton.titleLabel.font = [UIFont systemFontOfSize:13];
177   - [doneButton setTitle:@"完成" forState:UIControlStateDisabled];
178   - [doneButton setTitleColor:IP_RGBOF(0xFFFFFF) forState:UIControlStateDisabled];
179   - [doneButton setTitleColor:IP_RGBOF(0xFFFFFF) forState:UIControlStateNormal];
180   -
181   - //颜色绘制成图片
182   - UIImage *dis_image = [UIImage ip_imageWithColor:IP_RGBAOF(0x0BBE06, 0.5)];
183   - [doneButton setBackgroundImage:dis_image forState:UIControlStateSelected];
184   - UIImage *nor_image = [UIImage ip_imageWithColor:IP_RGBOF(0x0BBE06)];
185   - [doneButton setBackgroundImage:nor_image forState:UIControlStateNormal];
186   - doneButton.layer.masksToBounds = YES;
187   - doneButton.layer.cornerRadius = 5;
188   - }];
189   -
190   - //视频预览
191   - [self setVideoPreviewPageUIConfigBlock:^(UIButton *playButton, UIView *toolBar, UIButton *doneButton) {
192   -
193   - //完成按钮
194   - doneButton.titleLabel.font = [UIFont systemFontOfSize:13];
195   - [doneButton setTitle:@"完成" forState:UIControlStateDisabled];
196   - [doneButton setTitleColor:IP_RGBOF(0xFFFFFF) forState:UIControlStateDisabled];
197   - [doneButton setTitleColor:IP_RGBOF(0xFFFFFF) forState:UIControlStateNormal];
198   -
199   - //颜色绘制成图片
200   - UIImage *dis_image = [UIImage ip_imageWithColor:IP_RGBAOF(0x0BBE06, 0.5)];
201   - [doneButton setBackgroundImage:dis_image forState:UIControlStateSelected];
202   - UIImage *nor_image = [UIImage ip_imageWithColor:IP_RGBOF(0x0BBE06)];
203   - [doneButton setBackgroundImage:nor_image forState:UIControlStateNormal];
204   - doneButton.layer.masksToBounds = YES;
205   - doneButton.layer.cornerRadius = 5;
206   -
207   - }];
208   -
209   - //gif预览
210   - [self setGifPreviewPageUIConfigBlock:^(UIView *toolBar, UIButton *doneButton) {
211   -
212   - //完成按钮
213   - doneButton.titleLabel.font = [UIFont systemFontOfSize:13];
214   - [doneButton setTitle:@"完成" forState:UIControlStateDisabled];
215   - [doneButton setTitleColor:IP_RGBOF(0xFFFFFF) forState:UIControlStateDisabled];
216   - [doneButton setTitleColor:IP_RGBOF(0xFFFFFF) forState:UIControlStateNormal];
217   -
218   - //颜色绘制成图片
219   - UIImage *dis_image = [UIImage ip_imageWithColor:IP_RGBAOF(0x0BBE06, 0.5)];
220   - [doneButton setBackgroundImage:dis_image forState:UIControlStateSelected];
221   - UIImage *nor_image = [UIImage ip_imageWithColor:IP_RGBOF(0x0BBE06)];
222   - [doneButton setBackgroundImage:nor_image forState:UIControlStateNormal];
223   - doneButton.layer.masksToBounds = YES;
224   - doneButton.layer.cornerRadius = 5;
225   -
226   - }];
227   - //相册cell
228   - [self setAssetCellDidSetModelBlock:^(TZAssetCell *cell, UIImageView *imageView, UIImageView *selectImageView, UILabel *indexLabel, UIView *bottomView, UILabel *timeLength, UIImageView *videoImgView) {
229   -
230   -
231   - }];
232   - //相簿
233   - [self setAlbumCellDidSetModelBlock:^(TZAlbumCell *cell, UIImageView *posterImageView, UILabel *titleLabel) {
234   - [posterImageView setBackgroundColor:[UIColor blueColor]];
235   - [posterImageView setBackgroundColor:[UIColor blueColor]];
236   -
237   - }];
238   -
239   -
240   - /// 【自定义各页面/组件的frame】在界面viewDidLayoutSubviews/组件layoutSubviews后调用,允许外界修改frame等
241   - //相册
242   - [self setPhotoPickerPageDidLayoutSubviewsBlock:^(UICollectionView *collectionView, UIView *bottomToolBar, UIButton *previewButton, UIButton *originalPhotoButton, UILabel *originalPhotoLabel, UIButton *doneButton, UIImageView *numberImageView, UILabel *numberLabel, UIView *divideLine) {
243   -
244   - CGRect frame = bottomToolBar.frame;
245   - doneButton.frame = CGRectMake(frame.size.width - 60 - 13, frame.size.height /2 - 15 - (kIPVerticalBottomSafeHeight /2), 60, 30);
246   -
247   - CGRect originalPhotoLabelFrame = originalPhotoLabel.frame;
248   - CGFloat originalX = (bottomToolBar.frame.size.width - originalPhotoLabelFrame.size.width) /2;
249   - CGFloat originalY = originalPhotoLabelFrame.origin.y;
250   - originalPhotoButton.frame = CGRectMake(originalX, originalY, originalPhotoLabelFrame.size.width, originalPhotoLabelFrame.size.height);
251   -
252   -
253   - }];
254   - //图片预览
255   - [self setPhotoPreviewPageDidLayoutSubviewsBlock:^(UICollectionView *collectionView, UIView *naviBar, UIButton *backButton, UIButton *selectButton, UILabel *indexLabel, UIView *toolBar, UIButton *originalPhotoButton, UILabel *originalPhotoLabel, UIButton *doneButton, UIImageView *numberImageView, UILabel *numberLabel) {
256   -
257   - CGRect frame = toolBar.frame;
258   - doneButton.frame = CGRectMake(frame.size.width - 60 - 13, frame.size.height /2 - 15 - (kIPVerticalBottomSafeHeight /2), 60, 30);
259   -
260   - }];
261   - //视频预览
262   - [self setVideoPreviewPageDidLayoutSubviewsBlock:^(UIButton *playButton, UIView *toolBar, UIButton *doneButton) {
263   -
264   - CGRect frame = toolBar.frame;
265   - doneButton.frame = CGRectMake(frame.size.width - 60 - 13, frame.size.height /2 - 15 - (kIPVerticalBottomSafeHeight /2), 60, 30);
266   -
267   - }];
268   - //gif预览
269   - [self setGifPreviewPageDidLayoutSubviewsBlock:^(UIView *toolBar, UIButton *doneButton) {
270   -
271   - CGRect frame = toolBar.frame;
272   - doneButton.frame = CGRectMake(frame.size.width - 60 - 13, frame.size.height /2 - 15 - (kIPVerticalBottomSafeHeight /2), 60, 30);
273   -
274   - }];
275   - //相册cell
276   -
277   - [self setAssetCellDidLayoutSubviewsBlock:^(TZAssetCell *cell, UIImageView *imageView, UIImageView *selectImageView, UILabel *indexLabel, UIView *bottomView, UILabel *timeLength, UIImageView *videoImgView) {
278   - }];
279   - //相簿
280   - [self setAlbumCellDidLayoutSubviewsBlock:^(TZAlbumCell *cell, UIImageView *posterImageView, UILabel *titleLabel) {
281   -
282   - }];
283   -
284   - //设置图片个数
285   - self.photoNumberIconImage = [UIImage new];
286   -
287   -}
288   -
289   -- (void)didReceiveMemoryWarning {
290   - [super didReceiveMemoryWarning];
291   - // Dispose of any resources that can be recreated.
292   -}
293   -
294   -
295   -@end
CNLiveImagePickerController/CNImagePickerManager.h deleted 100644 → 0
1   -//
2   -// CNImagePickerManager.h
3   -// CNLiveNetAdd
4   -//
5   -// Created by 梁星国 on 2018/10/8.
6   -// Copyright © 2018年 cnlive. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -#import <Foundation/Foundation.h>
11   -#import "CNImagePickerController.h"
12   -
13   -
14   -typedef void (^didFinishPickingPhotosHandle)(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto);//选着图片返回
15   -
16   -//typedef void (^failureBlock)(NSMutableArray* errorArray, NSError *error);//失败数组,错误
17   -
18   -typedef NS_ENUM(NSUInteger, CNImagePickerEnterType) {
19   - CNImagePickerEnterTypeFriendsCircle = 0,//朋友圈
20   - CNImagePickerEnterTypeComment = 1,//评论
21   - CNImagePickerEnterTypeSweepCode = 2,//扫码
22   - CNImagePickerEnterTypeChat = 3,//聊天
23   - CNImagePickerEnterTypeOther = 4,//其他
24   - CNImagePickerEnterTypeWitness = 5, //目击者
25   -
26   -};
27   -@interface CNImagePickerManager : NSObject
28   -
29   -
30   -
31   -/**
32   - 打开相册选择图片
33   -
34   - @param maxImagesCount 最大图片
35   - @param columnNumber 列个数
36   - @param delegate 代理(UIViewController<TZImagePickerControllerDelegate>)
37   - @param pushPhotoPickerVc 是否跳转到相册
38   - @param isSelectOriginalPhoto 是否原图
39   - @param selectedAssets 选择图片
40   - @param enterType 进入方式
41   - @param pickingPhotosHandle 选择结束回调
42   - */
43   -+ (void)ImagePickerWithMaxImagesCount:(NSInteger)maxImagesCount columnNumber:(NSInteger)columnNumber delegate:(id<TZImagePickerControllerDelegate>)delegate pushPhotoPickerVc:(BOOL)pushPhotoPickerVc isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto selectedAssets:(NSMutableArray *)selectedAssets enterType:(CNImagePickerEnterType )enterType pickingPhotosHandle:(didFinishPickingPhotosHandle) pickingPhotosHandle;
44   -
45   -/**
46   - 预览图片
47   -
48   - @param maxImagesCount 最大限制
49   - @param delegate 代理(UIViewController<TZImagePickerControllerDelegate>)
50   - @param selectedAssets 选中Assets
51   - @param selectedPhotos 选中Photos
52   - @param index 选中第几个
53   - @param isSelectOriginalPhoto 是否原图
54   - @param enterType 进入方式
55   - @param pickingPhotosHandle 回调参数
56   - */
57   -+ (void)ImagePickerWithMaxImagesCount:(NSInteger)maxImagesCount delegate:(id<TZImagePickerControllerDelegate>)delegate selectedAssets:(NSMutableArray *)selectedAssets selectedPhotos:(NSMutableArray *)selectedPhotos index:(NSInteger)index isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto enterType:(CNImagePickerEnterType )enterType pickingPhotosHandle:(didFinishPickingPhotosHandle) pickingPhotosHandle;
58   -
59   -
60   -/**
61   - 预览单个视频
62   -
63   - @param selectedAsset 选择视频
64   - @param delegate 代理(UIViewController<TZImagePickerControllerDelegate>)
65   - */
66   -+ (void)ImagePickerWithSelectedAsset:(id)selectedAsset delegate:(id<TZImagePickerControllerDelegate>)delegate;
67   -
68   -
69   -/**
70   - 保存图片
71   -
72   - @param delegate 代理(UIViewController<TZImagePickerControllerDelegate>)
73   - @param image 图片
74   - @param location 地点
75   - @param success 成功
76   - @param failure 失败
77   -
78   - */
79   -+(void)ImageManagerSavePhotoWithDelegate:(id<TZImagePickerControllerDelegate>)delegate image:(UIImage *)image location:(CLLocation *)location success:(void (^)(TZAssetModel *assetModel))success failure:(void (^)(NSError *error))failure;
80   -
81   -
82   -/**
83   - 判断Asset类型
84   -
85   - @param asset asset
86   - @return 返回类型
87   - */
88   -+ (TZAssetModelMediaType)getAssetType:(id)asset;
89   -
90   -
91   -@end
92   -
CNLiveImagePickerController/CNImagePickerManager.m deleted 100644 → 0
1   -//
2   -// CNImagePickerManager.m
3   -// CNLiveNetAdd
4   -//
5   -// Created by 梁星国 on 2018/10/8.
6   -// Copyright © 2018年 cnlive. All rights reserved.
7   -//
8   -
9   -#import "CNImagePickerManager.h"
10   -#import <AssetsLibrary/AssetsLibrary.h>
11   -#import "CNImagePickerCommonDefine.h"
12   -
13   -@implementation CNImagePickerManager
14   -
15   -/// 打开相册选择图片
16   -+ (void)ImagePickerWithMaxImagesCount:(NSInteger)maxImagesCount columnNumber:(NSInteger)columnNumber delegate:(id<TZImagePickerControllerDelegate>)delegate pushPhotoPickerVc:(BOOL)pushPhotoPickerVc isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto selectedAssets:(NSMutableArray *)selectedAssets enterType:(CNImagePickerEnterType )enterType pickingPhotosHandle:(didFinishPickingPhotosHandle) pickingPhotosHandle{
17   -
18   - if (![delegate isKindOfClass:[UIViewController class]]) {
19   - return;
20   - }
21   - UIViewController *vc = (UIViewController *)delegate;
22   -
23   - CNImagePickerController *imagePickerVc = [[CNImagePickerController alloc] initWithMaxImagesCount:maxImagesCount columnNumber:columnNumber delegate:delegate pushPhotoPickerVc:pushPhotoPickerVc];
24   - [imagePickerVc configTZImagePicker];//基本配置
25   - //特殊配置
26   - switch (enterType) {
27   - case CNImagePickerEnterTypeFriendsCircle:
28   - imagePickerVc.maxEditVideoTime = kFriendsCircle_limit_video_maxEdit;//编辑长度
29   - imagePickerVc.maxVideoDuration = kFriendsCircle_limit_video_max;//编辑视频最大长度
30   - // 3. 设置是否可以混选选择视频/图片/原图
31   - imagePickerVc.allowPickingMultipleVideo = NO;
32   - break;
33   - case CNImagePickerEnterTypeComment:
34   -
35   - break;
36   - case CNImagePickerEnterTypeSweepCode:
37   -
38   - break;
39   - case CNImagePickerEnterTypeChat:
40   - imagePickerVc.maxEditVideoTime = kFriendsCircle_limit_video_maxEdit;//编辑长度
41   - imagePickerVc.maxVideoDuration = kChat_limit_video_length;//编辑视频最大长度
42   -
43   - break;
44   - case CNImagePickerEnterTypeWitness:
45   - imagePickerVc.allowPickingImage = NO;// 显示图片
46   - imagePickerVc.allowPickingMultipleVideo = NO;
47   - imagePickerVc.maxEditVideoTime = kFriendsCircle_limit_video_maxEdit;//编辑长度
48   - imagePickerVc.maxVideoDuration = kFriendsCircle_limit_video_max;//编辑视频最大长度
49   - break;
50   - default://其他
51   - break;
52   - }
53   -
54   - imagePickerVc.isSelectOriginalPhoto = isSelectOriginalPhoto;//是否选择原图
55   - // 1.设置目前已经选中的图片数组
56   - imagePickerVc.selectedAssets = selectedAssets; // 目前已经选中的图片数组
57   - /// 5. Single selection mode, valid when maxImagesCount = 1
58   - /// 5. 单选模式,maxImagesCount为1时才生效
59   - // 设置竖屏下的裁剪尺寸
60   - NSInteger left = 30;
61   - NSInteger widthHeight = vc.view.frame.size.width - 2 * left;
62   - NSInteger top = (vc.view.frame.size.height - widthHeight) / 2;
63   - imagePickerVc.cropRect = CGRectMake(left, top, widthHeight, widthHeight);
64   - // 你可以通过block或者代理,来得到用户选择的照片.
65   - [imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
66   - // 回调参数
67   - !pickingPhotosHandle ? : pickingPhotosHandle(photos, assets, isSelectOriginalPhoto);
68   -
69   - }];
70   -
71   - [vc presentViewController:imagePickerVc animated:YES completion:nil];
72   -}
73   -
74   -/// 预览图片
75   -+ (void)ImagePickerWithMaxImagesCount:(NSInteger)maxImagesCount delegate:(id<TZImagePickerControllerDelegate>)delegate selectedAssets:(NSMutableArray *)selectedAssets selectedPhotos:(NSMutableArray *)selectedPhotos index:(NSInteger)index isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto enterType:(CNImagePickerEnterType )enterType pickingPhotosHandle:(didFinishPickingPhotosHandle) pickingPhotosHandle {
76   -
77   - if (![delegate isKindOfClass:[UIViewController class]]) {
78   - return;
79   - }
80   - UIViewController *vc = (UIViewController *)delegate;
81   -
82   - CNImagePickerController *imagePickerVc = [[CNImagePickerController alloc] initWithSelectedAssets:selectedAssets selectedPhotos:selectedPhotos index:index];
83   - [imagePickerVc configTZImagePicker];//基本配置
84   - //特殊配置
85   - switch (enterType) {
86   - case CNImagePickerEnterTypeFriendsCircle:
87   - imagePickerVc.allowPickingGif = NO;
88   - imagePickerVc.allowPickingOriginalPhoto = YES;
89   - imagePickerVc.allowPickingMultipleVideo = NO;
90   - break;
91   - case CNImagePickerEnterTypeComment:
92   -#pragma mark - TODO:根据不同设置
93   - break;
94   - case CNImagePickerEnterTypeSweepCode:
95   -
96   - break;
97   - case CNImagePickerEnterTypeChat:
98   -
99   - break;
100   - case CNImagePickerEnterTypeOther:
101   - break;
102   - default://其他
103   - break;
104   - }
105   -
106   - imagePickerVc.maxImagesCount = maxImagesCount;
107   - imagePickerVc.isSelectOriginalPhoto = isSelectOriginalPhoto;
108   -
109   - [imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
110   - // 回调参数
111   - !pickingPhotosHandle ? : pickingPhotosHandle(photos, assets, isSelectOriginalPhoto);
112   -
113   - }];
114   - [vc presentViewController:imagePickerVc animated:YES completion:nil];
115   -
116   -}
117   -
118   -/// 预览单个视频
119   -+ (void)ImagePickerWithSelectedAsset:(id)selectedAsset delegate:(id<TZImagePickerControllerDelegate>)delegate {
120   -
121   - if (![delegate isKindOfClass:[UIViewController class]]) {
122   - return;
123   - }
124   - UIViewController *vc = (UIViewController *)delegate;
125   -
126   - TZVideoPlayerController *videoVC = [[TZVideoPlayerController alloc] init];
127   - TZAssetModel *model = [TZAssetModel modelWithAsset:selectedAsset type:TZAssetModelMediaTypeVideo timeLength:@""];
128   - videoVC.isOther = YES;//(LXG)相册外进入
129   - videoVC.model = model;
130   - [vc presentViewController:videoVC animated:YES completion:nil];
131   -
132   -}
133   -
134   -/// 返回类型
135   -+ (TZAssetModelMediaType)getAssetType:(id)asset {
136   -
137   - TZAssetModelMediaType type = TZAssetModelMediaTypePhoto;
138   - if ([asset isKindOfClass:[PHAsset class]]) {
139   - PHAsset *phAsset = (PHAsset *)asset;
140   - if (phAsset.mediaType == PHAssetMediaTypeVideo) type = TZAssetModelMediaTypeVideo;
141   - else if (phAsset.mediaType == PHAssetMediaTypeAudio) type = TZAssetModelMediaTypeAudio;
142   - else if (phAsset.mediaType == PHAssetMediaTypeImage) {
143   - if (iOS9_1Later) {
144   - if (@available(iOS 9.1, *)) {
145   - if (phAsset.mediaSubtypes == PHAssetMediaSubtypePhotoLive)
146   - {
147   - type = TZAssetModelMediaTypeLivePhoto;
148   - }
149   - } else {
150   - // Fallback on earlier versions
151   - }
152   - }
153   - // Gif
154   - if ([[phAsset valueForKey:@"filename"] hasSuffix:@"GIF"]) {
155   - type = TZAssetModelMediaTypePhotoGif;
156   - }
157   - }
158   - } else {
159   - if ([[asset valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo]) {
160   - type = TZAssetModelMediaTypeVideo;
161   - }
162   - }
163   - return type;
164   -}
165   -
166   -
167   -+(void)ImageManagerSavePhotoWithDelegate:(id<TZImagePickerControllerDelegate>)delegate image:(UIImage *)image location:(CLLocation *)location success:(void (^)(TZAssetModel *assetModel))success failure:(void (^)(NSError *error))failure {
168   -
169   - TZImagePickerController *tzImagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:delegate];
170   - tzImagePickerVc.sortAscendingByModificationDate = YES;
171   -
172   - [tzImagePickerVc showProgressHUD];
173   - // save photo and get asset / 保存图片,获取到asset
174   - [[TZImageManager manager] savePhotoWithImage:image location:location completion:^(NSError *error){
175   -
176   - if (error) {
177   - [tzImagePickerVc hideProgressHUD];
178   - failure(error);
179   - NSLog(@"图片保存失败 %@",error);
180   - } else {
181   -
182   - [[TZImageManager manager] getCameraRollAlbum:NO allowPickingImage:YES needFetchAssets:YES completion:^(TZAlbumModel *model) {
183   - [[TZImageManager manager] getAssetsFromFetchResult:model.result allowPickingVideo:NO allowPickingImage:YES completion:^(NSArray<TZAssetModel *> *models) {
184   - [tzImagePickerVc hideProgressHUD];
185   - TZAssetModel *assetModel = [models firstObject];
186   - if (tzImagePickerVc.sortAscendingByModificationDate) {
187   - assetModel = [models lastObject];
188   - }
189   - success(assetModel);
190   - }];
191   -
192   - }];
193   - }
194   - }];
195   -
196   -}
197   -
198   -
199   -
200   -
201   -
202   -
203   -
204   -
205   -
206   -@end
CNLiveImagePickerController/Classes/.gitkeep 0 → 100644
CNLiveImagePickerController/Classes/ReplaceMe.m 0 → 100644
CNLiveImagePickerController/NSBundle+TZImagePicker.h deleted 100755 → 0
1   -//
2   -// NSBundle+TZImagePicker.h
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 16/08/18.
6   -// Copyright © 2016年 谭真. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -@interface NSBundle (TZImagePicker)
12   -
13   -+ (NSBundle *)tz_imagePickerBundle;
14   -
15   -+ (NSString *)tz_localizedStringForKey:(NSString *)key value:(NSString *)value;
16   -+ (NSString *)tz_localizedStringForKey:(NSString *)key;
17   -
18   -@end
19   -
CNLiveImagePickerController/NSBundle+TZImagePicker.m deleted 100755 → 0
1   -//
2   -// NSBundle+TZImagePicker.m
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 16/08/18.
6   -// Copyright © 2016年 谭真. All rights reserved.
7   -//
8   -
9   -#import "NSBundle+TZImagePicker.h"
10   -#import "TZImagePickerController.h"
11   -
12   -@implementation NSBundle (TZImagePicker)
13   -
14   -+ (NSBundle *)tz_imagePickerBundle {
15   - NSBundle *bundle = [NSBundle bundleForClass:[TZImagePickerController class]];
16   - NSURL *url = [bundle URLForResource:@"TZImagePickerController" withExtension:@"bundle"];
17   - bundle = [NSBundle bundleWithURL:url];
18   - return bundle;
19   -}
20   -
21   -+ (NSString *)tz_localizedStringForKey:(NSString *)key {
22   - return [self tz_localizedStringForKey:key value:@""];
23   -}
24   -
25   -+ (NSString *)tz_localizedStringForKey:(NSString *)key value:(NSString *)value {
26   - NSBundle *bundle = [TZImagePickerConfig sharedInstance].languageBundle;
27   - NSString *value1 = [bundle localizedStringForKey:key value:value table:nil];
28   - return value1;
29   -}
30   -
31   -@end
CNLiveImagePickerController/TZAssetCell.h deleted 100755 → 0
1   -//
2   -// TZAssetCell.h
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 15/12/24.
6   -// Copyright © 2015年 谭真. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -#import <Photos/Photos.h>
11   -
12   -typedef enum : NSUInteger {
13   - TZAssetCellTypePhoto = 0,
14   - TZAssetCellTypeLivePhoto,
15   - TZAssetCellTypePhotoGif,
16   - TZAssetCellTypeVideo,
17   - TZAssetCellTypeAudio,
18   -} TZAssetCellType;
19   -
20   -@class TZAssetModel;
21   -@interface TZAssetCell : UICollectionViewCell
22   -@property (weak, nonatomic) UIButton *selectPhotoButton;
23   -@property (weak, nonatomic) UIButton *cannotSelectLayerButton;
24   -@property (nonatomic, strong) TZAssetModel *model;
25   -@property (assign, nonatomic) NSInteger index;
26   -@property (nonatomic, copy) void (^didSelectPhotoBlock)(BOOL);
27   -@property (nonatomic, assign) TZAssetCellType type;
28   -@property (nonatomic, assign) BOOL allowPickingGif;
29   -@property (nonatomic, assign) BOOL allowPickingMultipleVideo;
30   -@property (nonatomic, copy) NSString *representedAssetIdentifier;
31   -@property (nonatomic, assign) int32_t imageRequestID;
32   -
33   -@property (nonatomic, strong) UIImage *photoSelImage;
34   -@property (nonatomic, strong) UIImage *photoDefImage;
35   -
36   -@property (nonatomic, assign) BOOL showSelectBtn;
37   -@property (assign, nonatomic) BOOL allowPreview;
38   -@property (assign, nonatomic) BOOL useCachedImage;
39   -
40   -@property (nonatomic, copy) void (^assetCellDidSetModelBlock)(TZAssetCell *cell, UIImageView *imageView, UIImageView *selectImageView, UILabel *indexLabel, UIView *bottomView, UILabel *timeLength, UIImageView *videoImgView);
41   -@property (nonatomic, copy) void (^assetCellDidLayoutSubviewsBlock)(TZAssetCell *cell, UIImageView *imageView, UIImageView *selectImageView, UILabel *indexLabel, UIView *bottomView, UILabel *timeLength, UIImageView *videoImgView);
42   -@end
43   -
44   -
45   -@class TZAlbumModel;
46   -@interface TZAlbumCell : UITableViewCell
47   -@property (nonatomic, strong) TZAlbumModel *model;
48   -@property (weak, nonatomic) UIButton *selectedCountButton;
49   -
50   -@property (nonatomic, copy) void (^albumCellDidSetModelBlock)(TZAlbumCell *cell, UIImageView *posterImageView, UILabel *titleLabel);
51   -@property (nonatomic, copy) void (^albumCellDidLayoutSubviewsBlock)(TZAlbumCell *cell, UIImageView *posterImageView, UILabel *titleLabel);
52   -@end
53   -
54   -
55   -@interface TZAssetCameraCell : UICollectionViewCell
56   -@property (nonatomic, strong) UIImageView *imageView;
57   -@end
CNLiveImagePickerController/TZAssetCell.m deleted 100755 → 0
1   -//
2   -// TZAssetCell.m
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 15/12/24.
6   -// Copyright © 2015年 谭真. All rights reserved.
7   -//
8   -
9   -#import "TZAssetCell.h"
10   -#import "TZAssetModel.h"
11   -#import "UIView+Layout.h"
12   -#import "TZImageManager.h"
13   -#import "TZImagePickerController.h"
14   -#import "TZProgressView.h"
15   -
16   -@interface TZAssetCell ()
17   -@property (weak, nonatomic) UIImageView *imageView; // The photo / 照片
18   -@property (weak, nonatomic) UIImageView *selectImageView;
19   -@property (weak, nonatomic) UILabel *indexLabel;
20   -@property (weak, nonatomic) UIView *bottomView;
21   -@property (weak, nonatomic) UILabel *timeLength;
22   -@property (strong, nonatomic) UITapGestureRecognizer *tapGesture;
23   -
24   -@property (nonatomic, weak) UIImageView *videoImgView;
25   -@property (nonatomic, strong) TZProgressView *progressView;
26   -@property (nonatomic, assign) int32_t bigImageRequestID;
27   -@end
28   -
29   -@implementation TZAssetCell
30   -
31   -- (void)setModel:(TZAssetModel *)model {
32   - _model = model;
33   - if (iOS8Later) {
34   - self.representedAssetIdentifier = [[TZImageManager manager] getAssetIdentifier:model.asset];
35   - }
36   - if (self.useCachedImage && model.cachedImage) {
37   - self.imageView.image = model.cachedImage;
38   - } else {
39   - self.model.cachedImage = nil;
40   - int32_t imageRequestID = [[TZImageManager manager] getPhotoWithAsset:model.asset photoWidth:self.tz_width completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
41   - // Set the cell's thumbnail image if it's still showing the same asset.
42   - if (!iOS8Later) {
43   - self.imageView.image = photo;
44   - self.model.cachedImage = photo;
45   - [self hideProgressView];
46   - return;
47   - }
48   - if ([self.representedAssetIdentifier isEqualToString:[[TZImageManager manager] getAssetIdentifier:model.asset]]) {
49   - self.imageView.image = photo;
50   - self.model.cachedImage = photo;
51   - } else {
52   - // NSLog(@"this cell is showing other asset");
53   - [[PHImageManager defaultManager] cancelImageRequest:self.imageRequestID];
54   - }
55   - if (!isDegraded) {
56   - [self hideProgressView];
57   - self.imageRequestID = 0;
58   - }
59   - } progressHandler:nil networkAccessAllowed:NO];
60   - if (imageRequestID && self.imageRequestID && imageRequestID != self.imageRequestID) {
61   - [[PHImageManager defaultManager] cancelImageRequest:self.imageRequestID];
62   - // NSLog(@"cancelImageRequest %d",self.imageRequestID);
63   - }
64   - self.imageRequestID = imageRequestID;
65   - }
66   - self.selectPhotoButton.selected = model.isSelected;
67   - self.selectImageView.image = self.selectPhotoButton.isSelected ? self.photoSelImage : self.photoDefImage;
68   - self.indexLabel.hidden = !self.selectPhotoButton.isSelected;
69   -
70   - self.type = (NSInteger)model.type;
71   - // 让宽度/高度小于 最小可选照片尺寸 的图片不能选中
72   - if (![[TZImageManager manager] isPhotoSelectableWithAsset:model.asset]) {
73   - if (_selectImageView.hidden == NO) {
74   - self.selectPhotoButton.hidden = YES;
75   - _selectImageView.hidden = YES;
76   - }
77   - }
78   - // 如果用户选中了该图片,提前获取一下大图
79   - if (model.isSelected) {
80   - [self requestBigImage];
81   - } else {
82   - [self cancelBigImageRequest];
83   - }
84   - if (model.needOscillatoryAnimation) {
85   - [UIView showOscillatoryAnimationWithLayer:self.selectImageView.layer type:TZOscillatoryAnimationToBigger];
86   - }
87   - model.needOscillatoryAnimation = NO;
88   - [self setNeedsLayout];
89   -
90   - if (self.assetCellDidSetModelBlock) {
91   - self.assetCellDidSetModelBlock(self, _imageView, _selectImageView, _indexLabel, _bottomView, _timeLength, _videoImgView);
92   - }
93   -}
94   -
95   -- (void)setIndex:(NSInteger)index {
96   - _index = index;
97   - self.indexLabel.text = [NSString stringWithFormat:@"%zd", index];
98   - [self.contentView bringSubviewToFront:self.indexLabel];
99   -}
100   -
101   -- (void)setShowSelectBtn:(BOOL)showSelectBtn {
102   - _showSelectBtn = showSelectBtn;
103   - BOOL selectable = [[TZImageManager manager] isPhotoSelectableWithAsset:self.model.asset];
104   - if (!self.selectPhotoButton.hidden) {
105   - self.selectPhotoButton.hidden = !showSelectBtn || !selectable;
106   - }
107   - if (!self.selectImageView.hidden) {
108   - self.selectImageView.hidden = !showSelectBtn || !selectable;
109   - }
110   -}
111   -
112   -- (void)setType:(TZAssetCellType)type {
113   - _type = type;
114   - if (type == TZAssetCellTypePhoto || type == TZAssetCellTypeLivePhoto || (type == TZAssetCellTypePhotoGif && !self.allowPickingGif) || self.allowPickingMultipleVideo) {
115   - _selectImageView.hidden = NO;
116   - _selectPhotoButton.hidden = NO;
117   - _bottomView.hidden = YES;
118   - } else { // Video of Gif
119   - _selectImageView.hidden = YES;
120   - _selectPhotoButton.hidden = YES;
121   - }
122   -
123   - if (type == TZAssetCellTypeVideo) {
124   - self.bottomView.hidden = NO;
125   - self.timeLength.text = _model.timeLength;
126   - self.videoImgView.hidden = NO;
127   - _timeLength.tz_left = self.videoImgView.tz_right;
128   - _timeLength.textAlignment = NSTextAlignmentRight;
129   - } else if (type == TZAssetCellTypePhotoGif && self.allowPickingGif) {
130   - self.bottomView.hidden = NO;
131   - self.timeLength.text = @"GIF";
132   - self.videoImgView.hidden = YES;
133   - _timeLength.tz_left = 5;
134   - _timeLength.textAlignment = NSTextAlignmentLeft;
135   - }
136   -}
137   -
138   -- (void)setAllowPreview:(BOOL)allowPreview {
139   - _allowPreview = allowPreview;
140   - if (allowPreview) {
141   - _imageView.userInteractionEnabled = NO;
142   - _tapGesture.enabled = NO;
143   - } else {
144   - _imageView.userInteractionEnabled = YES;
145   - _tapGesture.enabled = YES;
146   - }
147   -}
148   -
149   -- (void)selectPhotoButtonClick:(UIButton *)sender {
150   - if (self.didSelectPhotoBlock) {
151   - self.didSelectPhotoBlock(sender.isSelected);
152   - }
153   - self.selectImageView.image = sender.isSelected ? self.photoSelImage : self.photoDefImage;
154   - if (sender.isSelected) {
155   - if (![TZImagePickerConfig sharedInstance].showSelectedIndex && ![TZImagePickerConfig sharedInstance].showPhotoCannotSelectLayer) {
156   - [UIView showOscillatoryAnimationWithLayer:_selectImageView.layer type:TZOscillatoryAnimationToBigger];
157   - }
158   - // 用户选中了该图片,提前获取一下大图
159   - [self requestBigImage];
160   - } else { // 取消选中,取消大图的获取
161   - [self cancelBigImageRequest];
162   - }
163   -}
164   -
165   -/// 只在单选状态且allowPreview为NO时会有该事件
166   -- (void)didTapImageView {
167   - if (self.didSelectPhotoBlock) {
168   - self.didSelectPhotoBlock(NO);
169   - }
170   -}
171   -
172   -- (void)hideProgressView {
173   - if (_progressView) {
174   - self.progressView.hidden = YES;
175   - self.imageView.alpha = 1.0;
176   - }
177   -}
178   -
179   -- (void)requestBigImage {
180   - if (_bigImageRequestID) {
181   - [[PHImageManager defaultManager] cancelImageRequest:_bigImageRequestID];
182   - }
183   -
184   - _bigImageRequestID = [[TZImageManager manager] requestImageDataForAsset:_model.asset completion:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
185   - [self hideProgressView];
186   - } progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
187   - if (self.model.isSelected) {
188   - progress = progress > 0.02 ? progress : 0.02;;
189   - self.progressView.progress = progress;
190   - self.progressView.hidden = NO;
191   - self.imageView.alpha = 0.4;
192   - if (progress >= 1) {
193   - [self hideProgressView];
194   - }
195   - } else {
196   - *stop = YES;
197   - [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
198   - [self cancelBigImageRequest];
199   - }
200   - }];
201   -}
202   -
203   -- (void)cancelBigImageRequest {
204   - if (_bigImageRequestID) {
205   - [[PHImageManager defaultManager] cancelImageRequest:_bigImageRequestID];
206   - }
207   - [self hideProgressView];
208   -}
209   -
210   -#pragma mark - Lazy load
211   -
212   -- (UIButton *)selectPhotoButton {
213   - if (_selectPhotoButton == nil) {
214   - UIButton *selectPhotoButton = [[UIButton alloc] init];
215   - [selectPhotoButton addTarget:self action:@selector(selectPhotoButtonClick:) forControlEvents:UIControlEventTouchUpInside];
216   - [self.contentView addSubview:selectPhotoButton];
217   - _selectPhotoButton = selectPhotoButton;
218   - }
219   - return _selectPhotoButton;
220   -}
221   -
222   -- (UIImageView *)imageView {
223   - if (_imageView == nil) {
224   - UIImageView *imageView = [[UIImageView alloc] init];
225   - imageView.contentMode = UIViewContentModeScaleAspectFill;
226   - imageView.clipsToBounds = YES;
227   - [self.contentView addSubview:imageView];
228   - _imageView = imageView;
229   -
230   - _tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapImageView)];
231   - [_imageView addGestureRecognizer:_tapGesture];
232   - }
233   - return _imageView;
234   -}
235   -
236   -- (UIImageView *)selectImageView {
237   - if (_selectImageView == nil) {
238   - UIImageView *selectImageView = [[UIImageView alloc] init];
239   - selectImageView.contentMode = UIViewContentModeCenter;
240   - selectImageView.clipsToBounds = YES;
241   - [self.contentView addSubview:selectImageView];
242   - _selectImageView = selectImageView;
243   - }
244   - return _selectImageView;
245   -}
246   -
247   -- (UIView *)bottomView {
248   - if (_bottomView == nil) {
249   - UIView *bottomView = [[UIView alloc] init];
250   - static NSInteger rgb = 0;
251   - bottomView.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:0.8];
252   - [self.contentView addSubview:bottomView];
253   - _bottomView = bottomView;
254   - }
255   - return _bottomView;
256   -}
257   -
258   -- (UIButton *)cannotSelectLayerButton {
259   - if (_cannotSelectLayerButton == nil) {
260   - UIButton *cannotSelectLayerButton = [[UIButton alloc] init];
261   - [self.contentView addSubview:cannotSelectLayerButton];
262   - _cannotSelectLayerButton = cannotSelectLayerButton;
263   - }
264   - return _cannotSelectLayerButton;
265   -}
266   -
267   -- (UIImageView *)videoImgView {
268   - if (_videoImgView == nil) {
269   - UIImageView *videoImgView = [[UIImageView alloc] init];
270   - [videoImgView setImage:[UIImage imageNamedFromMyBundle:@"VideoSendIcon"]];
271   - [self.bottomView addSubview:videoImgView];
272   - _videoImgView = videoImgView;
273   - }
274   - return _videoImgView;
275   -}
276   -
277   -- (UILabel *)timeLength {
278   - if (_timeLength == nil) {
279   - UILabel *timeLength = [[UILabel alloc] init];
280   - timeLength.font = [UIFont boldSystemFontOfSize:11];
281   - timeLength.textColor = [UIColor whiteColor];
282   - timeLength.textAlignment = NSTextAlignmentRight;
283   - [self.bottomView addSubview:timeLength];
284   - _timeLength = timeLength;
285   - }
286   - return _timeLength;
287   -}
288   -
289   -- (UILabel *)indexLabel {
290   - if (_indexLabel == nil) {
291   - UILabel *indexLabel = [[UILabel alloc] init];
292   - indexLabel.font = [UIFont systemFontOfSize:14];
293   - indexLabel.textColor = [UIColor whiteColor];
294   - indexLabel.textAlignment = NSTextAlignmentCenter;
295   - [self.contentView addSubview:indexLabel];
296   - _indexLabel = indexLabel;
297   - }
298   - return _indexLabel;
299   -}
300   -
301   -- (TZProgressView *)progressView {
302   - if (_progressView == nil) {
303   - _progressView = [[TZProgressView alloc] init];
304   - _progressView.hidden = YES;
305   - [self addSubview:_progressView];
306   - }
307   - return _progressView;
308   -}
309   -
310   -- (void)layoutSubviews {
311   - [super layoutSubviews];
312   - _cannotSelectLayerButton.frame = self.bounds;
313   - if (self.allowPreview) {
314   - _selectPhotoButton.frame = CGRectMake(self.tz_width - 44, 0, 44, 44);
315   - } else {
316   - _selectPhotoButton.frame = self.bounds;
317   - }
318   - _selectImageView.frame = CGRectMake(self.tz_width - 27, 3, 24, 24);
319   - if (_selectImageView.image.size.width <= 27) {
320   - _selectImageView.contentMode = UIViewContentModeCenter;
321   - } else {
322   - _selectImageView.contentMode = UIViewContentModeScaleAspectFit;
323   - }
324   - _indexLabel.frame = _selectImageView.frame;
325   - _imageView.frame = CGRectMake(0, 0, self.tz_width, self.tz_height);
326   -
327   - static CGFloat progressWH = 20;
328   - CGFloat progressXY = (self.tz_width - progressWH) / 2;
329   - _progressView.frame = CGRectMake(progressXY, progressXY, progressWH, progressWH);
330   -
331   - _bottomView.frame = CGRectMake(0, self.tz_height - 17, self.tz_width, 17);
332   - _videoImgView.frame = CGRectMake(8, 0, 17, 17);
333   - _timeLength.frame = CGRectMake(self.videoImgView.tz_right, 0, self.tz_width - self.videoImgView.tz_right - 5, 17);
334   -
335   - self.type = (NSInteger)self.model.type;
336   - self.showSelectBtn = self.showSelectBtn;
337   -
338   - [self.contentView bringSubviewToFront:_bottomView];
339   - [self.contentView bringSubviewToFront:_cannotSelectLayerButton];
340   - [self.contentView bringSubviewToFront:_selectPhotoButton];
341   - [self.contentView bringSubviewToFront:_selectImageView];
342   - [self.contentView bringSubviewToFront:_indexLabel];
343   -
344   - if (self.assetCellDidLayoutSubviewsBlock) {
345   - self.assetCellDidLayoutSubviewsBlock(self, _imageView, _selectImageView, _indexLabel, _bottomView, _timeLength, _videoImgView);
346   - }
347   -}
348   -
349   -@end
350   -
351   -@interface TZAlbumCell ()
352   -@property (weak, nonatomic) UIImageView *posterImageView;
353   -@property (weak, nonatomic) UILabel *titleLabel;
354   -@end
355   -
356   -@implementation TZAlbumCell
357   -
358   -- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
359   - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
360   - self.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
361   - return self;
362   -}
363   -
364   -- (void)setModel:(TZAlbumModel *)model {
365   - _model = model;
366   -
367   - NSMutableAttributedString *nameString = [[NSMutableAttributedString alloc] initWithString:model.name attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16],NSForegroundColorAttributeName:[UIColor blackColor]}];
368   - NSAttributedString *countString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@" (%zd)",model.count] attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16],NSForegroundColorAttributeName:[UIColor lightGrayColor]}];
369   - [nameString appendAttributedString:countString];
370   - self.titleLabel.attributedText = nameString;
371   - [[TZImageManager manager] getPostImageWithAlbumModel:model completion:^(UIImage *postImage) {
372   - self.posterImageView.image = postImage;
373   - }];
374   - if (model.selectedCount) {
375   - self.selectedCountButton.hidden = NO;
376   - [self.selectedCountButton setTitle:[NSString stringWithFormat:@"%zd",model.selectedCount] forState:UIControlStateNormal];
377   - } else {
378   - self.selectedCountButton.hidden = YES;
379   - }
380   -
381   - if (self.albumCellDidSetModelBlock) {
382   - self.albumCellDidSetModelBlock(self, _posterImageView, _titleLabel);
383   - }
384   -}
385   -
386   -/// For fitting iOS6
387   -- (void)layoutSubviews {
388   - if (iOS7Later) [super layoutSubviews];
389   - _selectedCountButton.frame = CGRectMake(self.tz_width - 24 - 30, 23, 24, 24);
390   - NSInteger titleHeight = ceil(self.titleLabel.font.lineHeight);
391   - self.titleLabel.frame = CGRectMake(80, (self.tz_height - titleHeight) / 2, self.tz_width - 80 - 50, titleHeight);
392   - self.posterImageView.frame = CGRectMake(0, 0, 70, 70);
393   -
394   - if (self.albumCellDidLayoutSubviewsBlock) {
395   - self.albumCellDidLayoutSubviewsBlock(self, _posterImageView, _titleLabel);
396   - }
397   -}
398   -
399   -- (void)layoutSublayersOfLayer:(CALayer *)layer {
400   - if (iOS7Later) [super layoutSublayersOfLayer:layer];
401   -}
402   -
403   -#pragma mark - Lazy load
404   -
405   -- (UIImageView *)posterImageView {
406   - if (_posterImageView == nil) {
407   - UIImageView *posterImageView = [[UIImageView alloc] init];
408   - posterImageView.contentMode = UIViewContentModeScaleAspectFill;
409   - posterImageView.clipsToBounds = YES;
410   - [self.contentView addSubview:posterImageView];
411   - _posterImageView = posterImageView;
412   - }
413   - return _posterImageView;
414   -}
415   -
416   -- (UILabel *)titleLabel {
417   - if (_titleLabel == nil) {
418   - UILabel *titleLabel = [[UILabel alloc] init];
419   - titleLabel.font = [UIFont boldSystemFontOfSize:17];
420   - titleLabel.textColor = [UIColor blackColor];
421   - titleLabel.textAlignment = NSTextAlignmentLeft;
422   - [self.contentView addSubview:titleLabel];
423   - _titleLabel = titleLabel;
424   - }
425   - return _titleLabel;
426   -}
427   -
428   -- (UIButton *)selectedCountButton {
429   - if (_selectedCountButton == nil) {
430   - UIButton *selectedCountButton = [[UIButton alloc] init];
431   - selectedCountButton.layer.cornerRadius = 12;
432   - selectedCountButton.clipsToBounds = YES;
433   - selectedCountButton.backgroundColor = [UIColor redColor];
434   - [selectedCountButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
435   - selectedCountButton.titleLabel.font = [UIFont systemFontOfSize:15];
436   - [self.contentView addSubview:selectedCountButton];
437   - _selectedCountButton = selectedCountButton;
438   - }
439   - return _selectedCountButton;
440   -}
441   -
442   -@end
443   -
444   -
445   -
446   -@implementation TZAssetCameraCell
447   -
448   -- (instancetype)initWithFrame:(CGRect)frame {
449   - self = [super initWithFrame:frame];
450   - if (self) {
451   - self.backgroundColor = [UIColor whiteColor];
452   - _imageView = [[UIImageView alloc] init];
453   - _imageView.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.500];
454   - _imageView.contentMode = UIViewContentModeScaleAspectFill;
455   - [self.contentView addSubview:_imageView];
456   - self.clipsToBounds = YES;
457   - }
458   - return self;
459   -}
460   -
461   -- (void)layoutSubviews {
462   - [super layoutSubviews];
463   - _imageView.frame = self.bounds;
464   -}
465   -
466   -@end
CNLiveImagePickerController/TZAssetModel.h deleted 100755 → 0
1   -//
2   -// TZAssetModel.h
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 15/12/24.
6   -// Copyright © 2015年 谭真. All rights reserved.
7   -//
8   -
9   -#import <Foundation/Foundation.h>
10   -#import <UIKit/UIKit.h>
11   -
12   -typedef enum : NSUInteger {
13   - TZAssetModelMediaTypePhoto = 0,
14   - TZAssetModelMediaTypeLivePhoto,
15   - TZAssetModelMediaTypePhotoGif,
16   - TZAssetModelMediaTypeVideo,
17   - TZAssetModelMediaTypeAudio
18   -} TZAssetModelMediaType;
19   -
20   -@class PHAsset;
21   -@interface TZAssetModel : NSObject
22   -
23   -@property (nonatomic, strong) id asset; ///< PHAsset or ALAsset
24   -@property (nonatomic, assign) BOOL isSelected; ///< The select status of a photo, default is No
25   -@property (nonatomic, assign) TZAssetModelMediaType type;
26   -@property (assign, nonatomic) BOOL needOscillatoryAnimation;
27   -@property (nonatomic, copy) NSString *timeLength;
28   -@property (strong, nonatomic) UIImage *cachedImage;
29   -
30   -/// Init a photo dataModel With a asset
31   -/// 用一个PHAsset/ALAsset实例,初始化一个照片模型
32   -+ (instancetype)modelWithAsset:(id)asset type:(TZAssetModelMediaType)type;
33   -+ (instancetype)modelWithAsset:(id)asset type:(TZAssetModelMediaType)type timeLength:(NSString *)timeLength;
34   -
35   -@end
36   -
37   -
38   -@class PHFetchResult;
39   -@interface TZAlbumModel : NSObject
40   -
41   -@property (nonatomic, strong) NSString *name; ///< The album name
42   -@property (nonatomic, assign) NSInteger count; ///< Count of photos the album contain
43   -@property (nonatomic, strong) id result; ///< PHFetchResult<PHAsset> or ALAssetsGroup<ALAsset>
44   -
45   -@property (nonatomic, strong) NSArray *models;
46   -@property (nonatomic, strong) NSArray *selectedModels;
47   -@property (nonatomic, assign) NSUInteger selectedCount;
48   -
49   -@property (nonatomic, assign) BOOL isCameraRoll;
50   -
51   -- (void)setResult:(id)result needFetchAssets:(BOOL)needFetchAssets;
52   -
53   -@end
CNLiveImagePickerController/TZAssetModel.m deleted 100755 → 0
1   -//
2   -// TZAssetModel.m
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 15/12/24.
6   -// Copyright © 2015年 谭真. All rights reserved.
7   -//
8   -
9   -#import "TZAssetModel.h"
10   -#import "TZImageManager.h"
11   -
12   -@implementation TZAssetModel
13   -
14   -+ (instancetype)modelWithAsset:(id)asset type:(TZAssetModelMediaType)type{
15   - TZAssetModel *model = [[TZAssetModel alloc] init];
16   - model.asset = asset;
17   - model.isSelected = NO;
18   - model.type = type;
19   - return model;
20   -}
21   -
22   -+ (instancetype)modelWithAsset:(id)asset type:(TZAssetModelMediaType)type timeLength:(NSString *)timeLength {
23   - TZAssetModel *model = [self modelWithAsset:asset type:type];
24   - model.timeLength = timeLength;
25   - return model;
26   -}
27   -
28   -@end
29   -
30   -
31   -
32   -@implementation TZAlbumModel
33   -
34   -- (void)setResult:(id)result needFetchAssets:(BOOL)needFetchAssets {
35   - _result = result;
36   - if (needFetchAssets) {
37   - [[TZImageManager manager] getAssetsFromFetchResult:result completion:^(NSArray<TZAssetModel *> *models) {
38   - self->_models = models;
39   - if (self->_selectedModels) {
40   - [self checkSelectedModels];
41   - }
42   - }];
43   - }
44   -}
45   -
46   -- (void)setSelectedModels:(NSArray *)selectedModels {
47   - _selectedModels = selectedModels;
48   - if (_models) {
49   - [self checkSelectedModels];
50   - }
51   -}
52   -
53   -- (void)checkSelectedModels {
54   - self.selectedCount = 0;
55   - NSMutableArray *selectedAssets = [NSMutableArray array];
56   - for (TZAssetModel *model in _selectedModels) {
57   - [selectedAssets addObject:model.asset];
58   - }
59   - for (TZAssetModel *model in _models) {
60   - if ([[TZImageManager manager] isAssetsArray:selectedAssets containAsset:model.asset]) {
61   - self.selectedCount ++;
62   - }
63   - }
64   -}
65   -
66   -- (NSString *)name {
67   - if (_name) {
68   - return _name;
69   - }
70   - return @"";
71   -}
72   -
73   -@end
CNLiveImagePickerController/TZGifPhotoPreviewController.h deleted 100755 → 0
1   -//
2   -// TZGifPhotoPreviewController.h
3   -// TZImagePickerController
4   -//
5   -// Created by ttouch on 2016/12/13.
6   -// Copyright © 2016年 谭真. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -@class TZAssetModel;
12   -@interface TZGifPhotoPreviewController : UIViewController
13   -
14   -@property (nonatomic, strong) TZAssetModel *model;
15   -
16   -@end
CNLiveImagePickerController/TZGifPhotoPreviewController.m deleted 100755 → 0
1   -//
2   -// TZGifPhotoPreviewController.m
3   -// TZImagePickerController
4   -//
5   -// Created by ttouch on 2016/12/13.
6   -// Copyright © 2016年 谭真. All rights reserved.
7   -//
8   -
9   -#import "TZGifPhotoPreviewController.h"
10   -#import "TZImagePickerController.h"
11   -#import "TZAssetModel.h"
12   -#import "UIView+Layout.h"
13   -#import "TZPhotoPreviewCell.h"
14   -#import "TZImageManager.h"
15   -
16   -#pragma clang diagnostic push
17   -#pragma clang diagnostic ignored "-Wdeprecated-declarations"
18   -
19   -@interface TZGifPhotoPreviewController () {
20   - UIView *_toolBar;
21   - UIButton *_doneButton;
22   - UIProgressView *_progress;
23   -
24   - TZPhotoPreviewView *_previewView;
25   -
26   - UIStatusBarStyle _originStatusBarStyle;
27   -}
28   -@end
29   -
30   -@implementation TZGifPhotoPreviewController
31   -
32   -- (void)viewDidLoad {
33   - [super viewDidLoad];
34   - self.view.backgroundColor = [UIColor blackColor];
35   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
36   - if (tzImagePickerVc) {
37   - self.navigationItem.title = [NSString stringWithFormat:@"GIF %@",tzImagePickerVc.previewBtnTitleStr];
38   - }
39   - [self configPreviewView];
40   - [self configBottomToolBar];
41   -}
42   -
43   -- (void)viewWillAppear:(BOOL)animated {
44   - [super viewWillAppear:animated];
45   - _originStatusBarStyle = [UIApplication sharedApplication].statusBarStyle;
46   - [UIApplication sharedApplication].statusBarStyle = iOS7Later ? UIStatusBarStyleLightContent : UIStatusBarStyleBlackOpaque;
47   -}
48   -
49   -- (void)viewWillDisappear:(BOOL)animated {
50   - [super viewWillDisappear:animated];
51   - [UIApplication sharedApplication].statusBarStyle = _originStatusBarStyle;
52   -}
53   -
54   -- (void)configPreviewView {
55   - _previewView = [[TZPhotoPreviewView alloc] initWithFrame:CGRectZero];
56   - _previewView.model = self.model;
57   - __weak typeof(self) weakSelf = self;
58   - [_previewView setSingleTapGestureBlock:^{
59   - __strong typeof(weakSelf) strongSelf = weakSelf;
60   - [strongSelf signleTapAction];
61   - }];
62   - [self.view addSubview:_previewView];
63   -}
64   -
65   -- (void)configBottomToolBar {
66   - _toolBar = [[UIView alloc] initWithFrame:CGRectZero];
67   - CGFloat rgb = 34 / 255.0;
68   - _toolBar.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:0.7];
69   -
70   - _doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
71   - _doneButton.titleLabel.font = [UIFont systemFontOfSize:16];
72   - [_doneButton addTarget:self action:@selector(doneButtonClick) forControlEvents:UIControlEventTouchUpInside];
73   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
74   - if (tzImagePickerVc) {
75   - [_doneButton setTitle:tzImagePickerVc.doneBtnTitleStr forState:UIControlStateNormal];
76   - [_doneButton setTitleColor:tzImagePickerVc.oKButtonTitleColorNormal forState:UIControlStateNormal];
77   - } else {
78   - [_doneButton setTitle:[NSBundle tz_localizedStringForKey:@"Done"] forState:UIControlStateNormal];
79   - [_doneButton setTitleColor:[UIColor colorWithRed:(83/255.0) green:(179/255.0) blue:(17/255.0) alpha:1.0] forState:UIControlStateNormal];
80   - }
81   - [_toolBar addSubview:_doneButton];
82   -
83   - UILabel *byteLabel = [[UILabel alloc] init];
84   - byteLabel.textColor = [UIColor whiteColor];
85   - byteLabel.font = [UIFont systemFontOfSize:13];
86   - byteLabel.frame = CGRectMake(10, 0, 100, 44);
87   - [[TZImageManager manager] getPhotosBytesWithArray:@[_model] completion:^(NSString *totalBytes) {
88   - byteLabel.text = totalBytes;
89   - }];
90   - [_toolBar addSubview:byteLabel];
91   -
92   - [self.view addSubview:_toolBar];
93   -
94   - if (tzImagePickerVc.gifPreviewPageUIConfigBlock) {
95   - tzImagePickerVc.gifPreviewPageUIConfigBlock(_toolBar, _doneButton);
96   - }
97   -}
98   -
99   -#pragma mark - Layout
100   -
101   -- (void)viewDidLayoutSubviews {
102   - [super viewDidLayoutSubviews];
103   -
104   - _previewView.frame = self.view.bounds;
105   - _previewView.scrollView.frame = self.view.bounds;
106   - CGFloat toolBarHeight = [TZCommonTools tz_isIPhoneX] ? 44 + (83 - 49) : 44;
107   - _toolBar.frame = CGRectMake(0, self.view.tz_height - toolBarHeight, self.view.tz_width, toolBarHeight);
108   - _doneButton.frame = CGRectMake(self.view.tz_width - 44 - 12, 0, 44, 44);
109   -
110   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
111   - if (tzImagePickerVc.gifPreviewPageDidLayoutSubviewsBlock) {
112   - tzImagePickerVc.gifPreviewPageDidLayoutSubviewsBlock(_toolBar, _doneButton);
113   - }
114   -}
115   -
116   -#pragma mark - Click Event
117   -
118   -- (void)signleTapAction {
119   - _toolBar.hidden = !_toolBar.isHidden;
120   - [self.navigationController setNavigationBarHidden:_toolBar.isHidden];
121   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
122   - if (iOS7Later) {
123   - if (_toolBar.isHidden) {
124   - [UIApplication sharedApplication].statusBarHidden = YES;
125   - } else if (tzImagePickerVc.needShowStatusBar) {
126   - [UIApplication sharedApplication].statusBarHidden = NO;
127   - }
128   - }
129   -}
130   -
131   -- (void)doneButtonClick {
132   - if (self.navigationController) {
133   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
134   - if (imagePickerVc.autoDismiss) {
135   - [self.navigationController dismissViewControllerAnimated:YES completion:^{
136   - [self callDelegateMethod];
137   - }];
138   - } else {
139   - [self callDelegateMethod];
140   - }
141   - } else {
142   - [self dismissViewControllerAnimated:YES completion:^{
143   - [self callDelegateMethod];
144   - }];
145   - }
146   -}
147   -
148   -- (void)callDelegateMethod {
149   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
150   - UIImage *animatedImage = _previewView.imageView.image;
151   - if ([imagePickerVc.pickerDelegate respondsToSelector:@selector(imagePickerController:didFinishPickingGifImage:sourceAssets:)]) {
152   - [imagePickerVc.pickerDelegate imagePickerController:imagePickerVc didFinishPickingGifImage:animatedImage sourceAssets:_model.asset];
153   - }
154   - if (imagePickerVc.didFinishPickingGifImageHandle) {
155   - imagePickerVc.didFinishPickingGifImageHandle(animatedImage,_model.asset);
156   - }
157   -}
158   -
159   -#pragma clang diagnostic pop
160   -
161   -@end
CNLiveImagePickerController/TZImageCropManager.h deleted 100755 → 0
1   -//
2   -// TZImageCropManager.h
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 2016/12/5.
6   -// Copyright © 2016年 谭真. All rights reserved.
7   -// 图片裁剪管理类
8   -
9   -#import <Foundation/Foundation.h>
10   -#import <UIKit/UIKit.h>
11   -
12   -@interface TZImageCropManager : NSObject
13   -
14   -/// 裁剪框背景的处理
15   -+ (void)overlayClippingWithView:(UIView *)view cropRect:(CGRect)cropRect containerView:(UIView *)containerView needCircleCrop:(BOOL)needCircleCrop;
16   -
17   -/*
18   - 1.7.2 为了解决多位同学对于图片裁剪的需求,我这两天有空便在研究图片裁剪
19   - 幸好有tuyou的PhotoTweaks库做参考,裁剪的功能实现起来简单许多
20   - 该方法和其内部引用的方法基本来自于tuyou的PhotoTweaks库,我做了稍许删减和修改
21   - 感谢tuyou同学在github开源了优秀的裁剪库PhotoTweaks,表示感谢
22   - PhotoTweaks库的github链接:https://github.com/itouch2/PhotoTweaks
23   - */
24   -/// 获得裁剪后的图片
25   -+ (UIImage *)cropImageView:(UIImageView *)imageView toRect:(CGRect)rect zoomScale:(double)zoomScale containerView:(UIView *)containerView;
26   -
27   -/// 获取圆形图片
28   -+ (UIImage *)circularClipImage:(UIImage *)image;
29   -
30   -@end
31   -
32   -
33   -/// 该分类的代码来自SDWebImage:https://github.com/rs/SDWebImage
34   -/// 为了防止冲突,我将分类名字和方法名字做了修改
35   -@interface UIImage (TZGif)
36   -
37   -+ (UIImage *)sd_tz_animatedGIFWithData:(NSData *)data;
38   -
39   -@end
CNLiveImagePickerController/TZImageCropManager.m deleted 100755 → 0
1   -//
2   -// TZImageCropManager.m
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 2016/12/5.
6   -// Copyright © 2016年 谭真. All rights reserved.
7   -//
8   -
9   -#import "TZImageCropManager.h"
10   -#import "UIView+Layout.h"
11   -#import <ImageIO/ImageIO.h>
12   -#import "TZImageManager.h"
13   -#import "TZImagePickerController.h"
14   -
15   -@implementation TZImageCropManager
16   -
17   -/// 裁剪框背景的处理
18   -+ (void)overlayClippingWithView:(UIView *)view cropRect:(CGRect)cropRect containerView:(UIView *)containerView needCircleCrop:(BOOL)needCircleCrop {
19   - UIBezierPath *path= [UIBezierPath bezierPathWithRect:[UIScreen mainScreen].bounds];
20   - CAShapeLayer *layer = [CAShapeLayer layer];
21   - if (needCircleCrop) { // 圆形裁剪框
22   - [path appendPath:[UIBezierPath bezierPathWithArcCenter:containerView.center radius:cropRect.size.width / 2 startAngle:0 endAngle: 2 * M_PI clockwise:NO]];
23   - } else { // 矩形裁剪框
24   - [path appendPath:[UIBezierPath bezierPathWithRect:cropRect]];
25   - }
26   - layer.path = path.CGPath;
27   - layer.fillRule = kCAFillRuleEvenOdd;
28   - layer.fillColor = [[UIColor blackColor] CGColor];
29   - layer.opacity = 0.5;
30   - [view.layer addSublayer:layer];
31   -}
32   -
33   -/// 获得裁剪后的图片
34   -+ (UIImage *)cropImageView:(UIImageView *)imageView toRect:(CGRect)rect zoomScale:(double)zoomScale containerView:(UIView *)containerView {
35   - CGAffineTransform transform = CGAffineTransformIdentity;
36   - // 平移的处理
37   - CGRect imageViewRect = [imageView convertRect:imageView.bounds toView:containerView];
38   - CGPoint point = CGPointMake(imageViewRect.origin.x + imageViewRect.size.width / 2, imageViewRect.origin.y + imageViewRect.size.height / 2);
39   - CGFloat xMargin = containerView.tz_width - CGRectGetMaxX(rect) - rect.origin.x;
40   - CGPoint zeroPoint = CGPointMake((CGRectGetWidth(containerView.frame) - xMargin) / 2, containerView.center.y);
41   - CGPoint translation = CGPointMake(point.x - zeroPoint.x, point.y - zeroPoint.y);
42   - transform = CGAffineTransformTranslate(transform, translation.x, translation.y);
43   - // 缩放的处理
44   - transform = CGAffineTransformScale(transform, zoomScale, zoomScale);
45   -
46   - CGImageRef imageRef = [self newTransformedImage:transform
47   - sourceImage:imageView.image.CGImage
48   - sourceSize:imageView.image.size
49   - outputWidth:rect.size.width * [UIScreen mainScreen].scale
50   - cropSize:rect.size
51   - imageViewSize:imageView.frame.size];
52   - UIImage *cropedImage = [UIImage imageWithCGImage:imageRef];
53   - cropedImage = [[TZImageManager manager] fixOrientation:cropedImage];
54   - CGImageRelease(imageRef);
55   - return cropedImage;
56   -}
57   -
58   -+ (CGImageRef)newTransformedImage:(CGAffineTransform)transform sourceImage:(CGImageRef)sourceImage sourceSize:(CGSize)sourceSize outputWidth:(CGFloat)outputWidth cropSize:(CGSize)cropSize imageViewSize:(CGSize)imageViewSize {
59   - CGImageRef source = [self newScaledImage:sourceImage toSize:sourceSize];
60   -
61   - CGFloat aspect = cropSize.height/cropSize.width;
62   - CGSize outputSize = CGSizeMake(outputWidth, outputWidth*aspect);
63   -
64   - CGContextRef context = CGBitmapContextCreate(NULL, outputSize.width, outputSize.height, CGImageGetBitsPerComponent(source), 0, CGImageGetColorSpace(source), CGImageGetBitmapInfo(source));
65   - CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
66   - CGContextFillRect(context, CGRectMake(0, 0, outputSize.width, outputSize.height));
67   -
68   - CGAffineTransform uiCoords = CGAffineTransformMakeScale(outputSize.width / cropSize.width, outputSize.height / cropSize.height);
69   - uiCoords = CGAffineTransformTranslate(uiCoords, cropSize.width/2.0, cropSize.height / 2.0);
70   - uiCoords = CGAffineTransformScale(uiCoords, 1.0, -1.0);
71   - CGContextConcatCTM(context, uiCoords);
72   -
73   - CGContextConcatCTM(context, transform);
74   - CGContextScaleCTM(context, 1.0, -1.0);
75   -
76   - CGContextDrawImage(context, CGRectMake(-imageViewSize.width/2, -imageViewSize.height/2.0, imageViewSize.width, imageViewSize.height), source);
77   - CGImageRef resultRef = CGBitmapContextCreateImage(context);
78   - CGContextRelease(context);
79   - CGImageRelease(source);
80   - return resultRef;
81   -}
82   -
83   -+ (CGImageRef)newScaledImage:(CGImageRef)source toSize:(CGSize)size {
84   - CGSize srcSize = size;
85   - CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
86   - CGContextRef context = CGBitmapContextCreate(NULL, size.width, size.height, 8, 0, rgbColorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
87   - CGColorSpaceRelease(rgbColorSpace);
88   -
89   - CGContextSetInterpolationQuality(context, kCGInterpolationNone);
90   - CGContextTranslateCTM(context, size.width/2, size.height/2);
91   -
92   - CGContextDrawImage(context, CGRectMake(-srcSize.width/2, -srcSize.height/2, srcSize.width, srcSize.height), source);
93   -
94   - CGImageRef resultRef = CGBitmapContextCreateImage(context);
95   - CGContextRelease(context);
96   - return resultRef;
97   -}
98   -
99   -/// 获取圆形图片
100   -+ (UIImage *)circularClipImage:(UIImage *)image {
101   - UIGraphicsBeginImageContextWithOptions(image.size, NO, [UIScreen mainScreen].scale);
102   -
103   - CGContextRef ctx = UIGraphicsGetCurrentContext();
104   - CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
105   - CGContextAddEllipseInRect(ctx, rect);
106   - CGContextClip(ctx);
107   -
108   - [image drawInRect:rect];
109   - UIImage *circleImage = UIGraphicsGetImageFromCurrentImageContext();
110   -
111   - UIGraphicsEndImageContext();
112   - return circleImage;
113   -}
114   -
115   -@end
116   -
117   -
118   -@implementation UIImage (TZGif)
119   -
120   -+ (UIImage *)sd_tz_animatedGIFWithData:(NSData *)data {
121   - if (!data) {
122   - return nil;
123   - }
124   -
125   - CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
126   -
127   - size_t count = CGImageSourceGetCount(source);
128   -
129   - UIImage *animatedImage;
130   -
131   - if (count <= 1) {
132   - animatedImage = [[UIImage alloc] initWithData:data];
133   - }
134   - else {
135   - // images数组过大时内存会飙升,在这里限制下最大count
136   - NSInteger maxCount = [TZImagePickerConfig sharedInstance].gifPreviewMaxImagesCount ?: 200;
137   - NSInteger interval = MAX((count + maxCount / 2) / maxCount, 1);
138   -
139   - NSMutableArray *images = [NSMutableArray array];
140   -
141   - NSTimeInterval duration = 0.0f;
142   -
143   - for (size_t i = 0; i < count; i+=interval) {
144   - CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
145   - if (!image) {
146   - continue;
147   - }
148   -
149   - duration += [self sd_frameDurationAtIndex:i source:source] * MIN(interval, 3);
150   -
151   - [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
152   -
153   - CGImageRelease(image);
154   - }
155   -
156   - if (!duration) {
157   - duration = (1.0f / 10.0f) * count;
158   - }
159   -
160   - animatedImage = [UIImage animatedImageWithImages:images duration:duration];
161   - }
162   -
163   - CFRelease(source);
164   -
165   - return animatedImage;
166   -}
167   -
168   -+ (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
169   - float frameDuration = 0.1f;
170   - CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
171   - NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
172   - NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary];
173   -
174   - NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
175   - if (delayTimeUnclampedProp) {
176   - frameDuration = [delayTimeUnclampedProp floatValue];
177   - }
178   - else {
179   -
180   - NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
181   - if (delayTimeProp) {
182   - frameDuration = [delayTimeProp floatValue];
183   - }
184   - }
185   -
186   - // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
187   - // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
188   - // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>
189   - // for more information.
190   -
191   - if (frameDuration < 0.011f) {
192   - frameDuration = 0.100f;
193   - }
194   -
195   - CFRelease(cfFrameProperties);
196   - return frameDuration;
197   -}
198   -
199   -@end
CNLiveImagePickerController/TZImageManager.h deleted 100755 → 0
1   -//
2   -// TZImageManager.h
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 16/1/4.
6   -// Copyright © 2016年 谭真. All rights reserved.
7   -// 图片资源获取管理类
8   -
9   -#import <Foundation/Foundation.h>
10   -#import <UIKit/UIKit.h>
11   -#import <AVFoundation/AVFoundation.h>
12   -#import <Photos/Photos.h>
13   -#import "TZAssetModel.h"
14   -
15   -@class TZAlbumModel,TZAssetModel;
16   -@protocol TZImagePickerControllerDelegate;
17   -@interface TZImageManager : NSObject
18   -
19   -@property (nonatomic, strong) PHCachingImageManager *cachingImageManager;
20   -
21   -+ (instancetype)manager NS_SWIFT_NAME(default());
22   -+ (void)deallocManager;
23   -
24   -@property (weak, nonatomic) id<TZImagePickerControllerDelegate> pickerDelegate;
25   -
26   -#pragma mark - ADD: 原有逻辑-会话id(LXG)
27   -
28   -/// 导出路径
29   -@property (nonatomic, copy) NSString *outputPath;
30   -
31   -@property (nonatomic, assign) BOOL shouldFixOrientation;
32   -
33   -/// Default is 600px / 默认600像素宽
34   -@property (nonatomic, assign) CGFloat photoPreviewMaxWidth;
35   -/// The pixel width of output image, Default is 828px / 导出图片的宽度,默认828像素宽
36   -@property (nonatomic, assign) CGFloat photoWidth;
37   -
38   -/// Default is 4, Use in photos collectionView in TZPhotoPickerController
39   -/// 默认4列, TZPhotoPickerController中的照片collectionView
40   -@property (nonatomic, assign) NSInteger columnNumber;
41   -
42   -/// Sort photos ascending by modificationDate,Default is YES
43   -/// 对照片排序,按修改时间升序,默认是YES。如果设置为NO,最新的照片会显示在最前面,内部的拍照按钮会排在第一个
44   -@property (nonatomic, assign) BOOL sortAscendingByModificationDate;
45   -
46   -/// Minimum selectable photo width, Default is 0
47   -/// 最小可选中的图片宽度,默认是0,小于这个宽度的图片不可选中
48   -@property (nonatomic, assign) NSInteger minPhotoWidthSelectable;
49   -@property (nonatomic, assign) NSInteger minPhotoHeightSelectable;
50   -@property (nonatomic, assign) BOOL hideWhenCanNotSelect;
51   -
52   -/// Return YES if Authorized 返回YES如果得到了授权
53   -- (BOOL)authorizationStatusAuthorized;
54   -+ (NSInteger)authorizationStatus;
55   -- (void)requestAuthorizationWithCompletion:(void (^)(void))completion;
56   -
57   -/// Get Album 获得相册/相册数组
58   -- (void)getCameraRollAlbum:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage needFetchAssets:(BOOL)needFetchAssets completion:(void (^)(TZAlbumModel *model))completion;
59   -- (void)getAllAlbums:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage needFetchAssets:(BOOL)needFetchAssets completion:(void (^)(NSArray<TZAlbumModel *> *models))completion;
60   -
61   -/// Get Assets 获得Asset数组
62   -- (void)getAssetsFromFetchResult:(id)result completion:(void (^)(NSArray<TZAssetModel *> *models))completion;
63   -- (void)getAssetsFromFetchResult:(id)result allowPickingVideo:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage completion:(void (^)(NSArray<TZAssetModel *> *models))completion;
64   -- (void)getAssetFromFetchResult:(id)result atIndex:(NSInteger)index allowPickingVideo:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage completion:(void (^)(TZAssetModel *model))completion;
65   -
66   -/// Get photo 获得照片
67   -- (void)getPostImageWithAlbumModel:(TZAlbumModel *)model completion:(void (^)(UIImage *postImage))completion;
68   -
69   -- (int32_t)getPhotoWithAsset:(id)asset completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
70   -- (int32_t)getPhotoWithAsset:(id)asset photoWidth:(CGFloat)photoWidth completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
71   -- (int32_t)getPhotoWithAsset:(id)asset completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed;
72   -- (int32_t)getPhotoWithAsset:(id)asset photoWidth:(CGFloat)photoWidth completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed;
73   -- (int32_t)requestImageDataForAsset:(id)asset completion:(void (^)(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler;
74   -
75   -/// Get full Image 获取原图
76   -/// 如下两个方法completion一般会调多次,一般会先返回缩略图,再返回原图(详见方法内部使用的系统API的说明),如果info[PHImageResultIsDegradedKey] 为 YES,则表明当前返回的是缩略图,否则是原图。
77   -- (void)getOriginalPhotoWithAsset:(id)asset completion:(void (^)(UIImage *photo,NSDictionary *info))completion;
78   -- (void)getOriginalPhotoWithAsset:(id)asset newCompletion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
79   -// 该方法中,completion只会走一次
80   -- (void)getOriginalPhotoDataWithAsset:(id)asset completion:(void (^)(NSData *data,NSDictionary *info,BOOL isDegraded))completion;
81   -- (void)getOriginalPhotoDataWithAsset:(id)asset progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler completion:(void (^)(NSData *data,NSDictionary *info,BOOL isDegraded))completion;
82   -
83   -/// Save photo 保存照片
84   -- (void)savePhotoWithImage:(UIImage *)image completion:(void (^)(NSError *error))completion;
85   -- (void)savePhotoWithImage:(UIImage *)image location:(CLLocation *)location completion:(void (^)(NSError *error))completion;
86   -
87   -/// Save video 保存视频
88   -- (void)saveVideoWithUrl:(NSURL *)url completion:(void (^)(NSError *error))completion;
89   -- (void)saveVideoWithUrl:(NSURL *)url location:(CLLocation *)location completion:(void (^)(NSError *error))completion;
90   -
91   -/// Get video 获得视频
92   -- (void)getVideoWithAsset:(id)asset completion:(void (^)(AVPlayerItem * playerItem, NSDictionary * info))completion;
93   -- (void)getVideoWithAsset:(id)asset progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler completion:(void (^)(AVPlayerItem *, NSDictionary *))completion;
94   -
95   -/// Export video 导出视频 presetName: 预设名字,默认值是AVAssetExportPreset640x480
96   -- (void)getVideoOutputPathWithAsset:(id)asset success:(void (^)(NSString *outputPath))success failure:(void (^)(NSString *errorMessage, NSError *error))failure;
97   -- (void)getVideoOutputPathWithAsset:(id)asset presetName:(NSString *)presetName success:(void (^)(NSString *outputPath))success failure:(void (^)(NSString *errorMessage, NSError *error))failure;
98   -/// Deprecated, Use -getVideoOutputPathWithAsset:failure:success:
99   -- (void)getVideoOutputPathWithAsset:(id)asset completion:(void (^)(NSString *outputPath))completion __attribute__((deprecated("Use -getVideoOutputPathWithAsset:failure:success:")));
100   -
101   -/// Get photo bytes 获得一组照片的大小
102   -- (void)getPhotosBytesWithArray:(NSArray *)photos completion:(void (^)(NSString *totalBytes))completion;
103   -
104   -/// Judge is a assets array contain the asset 判断一个assets数组是否包含这个asset
105   -- (BOOL)isAssetsArray:(NSArray *)assets containAsset:(id)asset;
106   -
107   -- (NSString *)getAssetIdentifier:(id)asset;
108   -- (BOOL)isCameraRollAlbum:(id)metadata;
109   -
110   -/// 检查照片大小是否满足最小要求
111   -- (BOOL)isPhotoSelectableWithAsset:(id)asset;
112   -- (CGSize)photoSizeWithAsset:(id)asset;
113   -
114   -/// 修正图片转向
115   -- (UIImage *)fixOrientation:(UIImage *)aImage;
116   -
117   -/// 获取asset的资源类型
118   -- (TZAssetModelMediaType)getAssetType:(id)asset;
119   -/// 缩放图片至新尺寸
120   -- (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)size;
121   -
122   -/// 判断asset是否是视频
123   -- (BOOL)isVideo:(id)asset;
124   -
125   -@end
126   -
127   -//@interface TZSortDescriptor : NSSortDescriptor
128   -//
129   -//@end
CNLiveImagePickerController/TZImageManager.m deleted 100755 → 0
1   -//
2   -// TZImageManager.m
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 16/1/4.
6   -// Copyright © 2016年 谭真. All rights reserved.
7   -//
8   -
9   -#import "TZImageManager.h"
10   -#import <AssetsLibrary/AssetsLibrary.h>
11   -#import "TZAssetModel.h"
12   -#import "TZImagePickerController.h"
13   -
14   -@interface TZImageManager ()
15   -#pragma clang diagnostic push
16   -#pragma clang diagnostic ignored "-Wdeprecated-declarations"
17   -@property (nonatomic, strong) ALAssetsLibrary *assetLibrary;
18   -@end
19   -
20   -@implementation TZImageManager
21   -
22   -CGSize AssetGridThumbnailSize;
23   -CGFloat TZScreenWidth;
24   -CGFloat TZScreenScale;
25   -
26   -static TZImageManager *manager;
27   -static dispatch_once_t onceToken;
28   -
29   -+ (instancetype)manager {
30   - dispatch_once(&onceToken, ^{
31   - manager = [[self alloc] init];
32   - if (iOS8Later) {
33   - // manager.cachingImageManager = [[PHCachingImageManager alloc] init];
34   - // manager.cachingImageManager.allowsCachingHighQualityImages = YES;
35   - }
36   -
37   - [manager configTZScreenWidth];
38   - });
39   - return manager;
40   -}
41   -
42   -+ (void)deallocManager {
43   - onceToken = 0;
44   - manager = nil;
45   -}
46   -
47   -- (void)setPhotoWidth:(CGFloat)photoWidth {
48   - _photoWidth = photoWidth;
49   - TZScreenWidth = photoWidth / 2;
50   -}
51   -
52   -- (void)setColumnNumber:(NSInteger)columnNumber {
53   - [self configTZScreenWidth];
54   -
55   - _columnNumber = columnNumber;
56   - CGFloat margin = 4;
57   - CGFloat itemWH = (TZScreenWidth - 2 * margin - 4) / columnNumber - margin;
58   - AssetGridThumbnailSize = CGSizeMake(itemWH * TZScreenScale, itemWH * TZScreenScale);
59   -}
60   -
61   -- (void)configTZScreenWidth {
62   - TZScreenWidth = [UIScreen mainScreen].bounds.size.width;
63   - // 测试发现,如果scale在plus真机上取到3.0,内存会增大特别多。故这里写死成2.0
64   - TZScreenScale = 2.0;
65   - if (TZScreenWidth > 700) {
66   - TZScreenScale = 1.5;
67   - }
68   -}
69   -
70   -- (ALAssetsLibrary *)assetLibrary {
71   - if (_assetLibrary == nil) _assetLibrary = [[ALAssetsLibrary alloc] init];
72   - return _assetLibrary;
73   -}
74   -
75   -/// Return YES if Authorized 返回YES如果得到了授权
76   -- (BOOL)authorizationStatusAuthorized {
77   - NSInteger status = [self.class authorizationStatus];
78   - if (status == 0) {
79   - /**
80   - * 当某些情况下AuthorizationStatus == AuthorizationStatusNotDetermined时,无法弹出系统首次使用的授权alertView,系统应用设置里亦没有相册的设置,此时将无法使用,故作以下操作,弹出系统首次使用的授权alertView
81   - */
82   - [self requestAuthorizationWithCompletion:nil];
83   - }
84   -
85   - return status == 3;
86   -}
87   -
88   -+ (NSInteger)authorizationStatus {
89   - if (iOS8Later) {
90   - return [PHPhotoLibrary authorizationStatus];
91   - } else {
92   - return [ALAssetsLibrary authorizationStatus];
93   - }
94   - return NO;
95   -}
96   -
97   -- (void)requestAuthorizationWithCompletion:(void (^)(void))completion {
98   - void (^callCompletionBlock)(void) = ^(){
99   - dispatch_async(dispatch_get_main_queue(), ^{
100   - if (completion) {
101   - completion();
102   - }
103   - });
104   - };
105   -
106   - if (iOS8Later) {
107   - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
108   - [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
109   - callCompletionBlock();
110   - }];
111   - });
112   - } else {
113   - [self.assetLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
114   - callCompletionBlock();
115   - } failureBlock:^(NSError *error) {
116   - callCompletionBlock();
117   - }];
118   - }
119   -}
120   -
121   -#pragma mark - Get Album
122   -
123   -/// Get Album 获得相册/相册数组
124   -- (void)getCameraRollAlbum:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage needFetchAssets:(BOOL)needFetchAssets completion:(void (^)(TZAlbumModel *model))completion {
125   - __block TZAlbumModel *model;
126   - if (iOS8Later) {
127   - PHFetchOptions *option = [[PHFetchOptions alloc] init];
128   - if (!allowPickingVideo) option.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeImage];
129   - if (!allowPickingImage) option.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld",
130   - PHAssetMediaTypeVideo];
131   - // option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"modificationDate" ascending:self.sortAscendingByModificationDate]];
132   - if (!self.sortAscendingByModificationDate) {
133   - option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:self.sortAscendingByModificationDate]];
134   - }
135   - PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
136   - for (PHAssetCollection *collection in smartAlbums) {
137   - // 有可能是PHCollectionList类的的对象,过滤掉
138   - if (![collection isKindOfClass:[PHAssetCollection class]]) continue;
139   - // 过滤空相册
140   - if (collection.estimatedAssetCount <= 0) continue;
141   - if ([self isCameraRollAlbum:collection]) {
142   - PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:option];
143   - model = [self modelWithResult:fetchResult name:collection.localizedTitle isCameraRoll:YES needFetchAssets:needFetchAssets];
144   - if (completion) completion(model);
145   - break;
146   - }
147   - }
148   - } else {
149   - [self.assetLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
150   - if ([group numberOfAssets] < 1) return;
151   - if ([self isCameraRollAlbum:group]) {
152   - NSString *name = [group valueForProperty:ALAssetsGroupPropertyName];
153   - model = [self modelWithResult:group name:name isCameraRoll:YES needFetchAssets:needFetchAssets];
154   - if (completion) completion(model);
155   - *stop = YES;
156   - }
157   - } failureBlock:nil];
158   - }
159   -}
160   -
161   -- (void)getAllAlbums:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage needFetchAssets:(BOOL)needFetchAssets completion:(void (^)(NSArray<TZAlbumModel *> *))completion{
162   - NSMutableArray *albumArr = [NSMutableArray array];
163   - if (iOS8Later) {
164   - PHFetchOptions *option = [[PHFetchOptions alloc] init];
165   - if (!allowPickingVideo) option.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld", PHAssetMediaTypeImage];
166   - if (!allowPickingImage) option.predicate = [NSPredicate predicateWithFormat:@"mediaType == %ld",
167   - PHAssetMediaTypeVideo];
168   - // option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"modificationDate" ascending:self.sortAscendingByModificationDate]];
169   - if (!self.sortAscendingByModificationDate) {
170   - option.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:self.sortAscendingByModificationDate]];
171   - }
172   - // 我的照片流 1.6.10重新加入..
173   - PHFetchResult *myPhotoStreamAlbum = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumMyPhotoStream options:nil];
174   - PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];
175   - PHFetchResult *topLevelUserCollections = [PHCollectionList fetchTopLevelUserCollectionsWithOptions:nil];
176   - PHFetchResult *syncedAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumSyncedAlbum options:nil];
177   - PHFetchResult *sharedAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAlbumCloudShared options:nil];
178   - NSArray *allAlbums = @[myPhotoStreamAlbum,smartAlbums,topLevelUserCollections,syncedAlbums,sharedAlbums];
179   - for (PHFetchResult *fetchResult in allAlbums) {
180   - for (PHAssetCollection *collection in fetchResult) {
181   - // 有可能是PHCollectionList类的的对象,过滤掉
182   - if (![collection isKindOfClass:[PHAssetCollection class]]) continue;
183   - // 过滤空相册
184   - if (collection.estimatedAssetCount <= 0) continue;
185   - PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:option];
186   - if (fetchResult.count < 1) continue;
187   -
188   - if ([self.pickerDelegate respondsToSelector:@selector(isAlbumCanSelect:result:)]) {
189   - if (![self.pickerDelegate isAlbumCanSelect:collection.localizedTitle result:fetchResult]) {
190   - continue;
191   - }
192   - }
193   -
194   - if (collection.assetCollectionSubtype == PHAssetCollectionSubtypeSmartAlbumAllHidden) continue;
195   - if (collection.assetCollectionSubtype == 1000000201) continue; //『最近删除』相册
196   - if ([self isCameraRollAlbum:collection]) {
197   - [albumArr insertObject:[self modelWithResult:fetchResult name:collection.localizedTitle isCameraRoll:YES needFetchAssets:needFetchAssets] atIndex:0];
198   - } else {
199   - [albumArr addObject:[self modelWithResult:fetchResult name:collection.localizedTitle isCameraRoll:NO needFetchAssets:needFetchAssets]];
200   - }
201   - }
202   - }
203   - if (completion && albumArr.count > 0) completion(albumArr);
204   - } else {
205   - [self.assetLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
206   - if (group == nil) {
207   - if (completion && albumArr.count > 0) completion(albumArr);
208   - }
209   - if ([group numberOfAssets] < 1) return;
210   - NSString *name = [group valueForProperty:ALAssetsGroupPropertyName];
211   -
212   - if ([self.pickerDelegate respondsToSelector:@selector(isAlbumCanSelect:result:)]) {
213   - if (![self.pickerDelegate isAlbumCanSelect:name result:group]) {
214   - return;
215   - }
216   - }
217   -
218   - if ([self isCameraRollAlbum:group]) {
219   - [albumArr insertObject:[self modelWithResult:group name:name isCameraRoll:YES needFetchAssets:needFetchAssets] atIndex:0];
220   - } else if ([[group valueForProperty:ALAssetsGroupPropertyType] intValue] == ALAssetsGroupPhotoStream) {
221   - if (albumArr.count) {
222   - [albumArr insertObject:[self modelWithResult:group name:name isCameraRoll:NO needFetchAssets:needFetchAssets] atIndex:1];
223   - } else {
224   - [albumArr addObject:[self modelWithResult:group name:name isCameraRoll:NO needFetchAssets:needFetchAssets]];
225   - }
226   - } else {
227   - [albumArr addObject:[self modelWithResult:group name:name isCameraRoll:NO needFetchAssets:needFetchAssets]];
228   - }
229   - } failureBlock:nil];
230   - }
231   -}
232   -
233   -#pragma mark - Get Assets
234   -
235   -/// Get Assets 获得照片数组
236   -- (void)getAssetsFromFetchResult:(id)result completion:(void (^)(NSArray<TZAssetModel *> *))completion {
237   - TZImagePickerConfig *config = [TZImagePickerConfig sharedInstance];
238   - return [self getAssetsFromFetchResult:result allowPickingVideo:config.allowPickingVideo allowPickingImage:config.allowPickingImage completion:completion];
239   -}
240   -
241   -- (void)getAssetsFromFetchResult:(id)result allowPickingVideo:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage completion:(void (^)(NSArray<TZAssetModel *> *))completion {
242   - NSMutableArray *photoArr = [NSMutableArray array];
243   - if ([result isKindOfClass:[PHFetchResult class]]) {
244   - PHFetchResult *fetchResult = (PHFetchResult *)result;
245   - [fetchResult enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
246   - TZAssetModel *model = [self assetModelWithAsset:obj allowPickingVideo:allowPickingVideo allowPickingImage:allowPickingImage];
247   - if (model) {
248   - [photoArr addObject:model];
249   - }
250   - }];
251   - if (completion) completion(photoArr);
252   - } else if ([result isKindOfClass:[ALAssetsGroup class]]) {
253   - ALAssetsGroup *group = (ALAssetsGroup *)result;
254   - if (allowPickingImage && allowPickingVideo) {
255   - [group setAssetsFilter:[ALAssetsFilter allAssets]];
256   - } else if (allowPickingVideo) {
257   - [group setAssetsFilter:[ALAssetsFilter allVideos]];
258   - } else if (allowPickingImage) {
259   - [group setAssetsFilter:[ALAssetsFilter allPhotos]];
260   - }
261   - ALAssetsGroupEnumerationResultsBlock resultBlock = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
262   - if (result == nil) {
263   - if (completion) completion(photoArr);
264   - }
265   - TZAssetModel *model = [self assetModelWithAsset:result allowPickingVideo:allowPickingVideo allowPickingImage:allowPickingImage];
266   - if (model) {
267   - [photoArr addObject:model];
268   - }
269   - };
270   - if (self.sortAscendingByModificationDate) {
271   - [group enumerateAssetsUsingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
272   - if (resultBlock) { resultBlock(result,index,stop); }
273   - }];
274   - } else {
275   - [group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
276   - if (resultBlock) {resultBlock(result,index,stop); }
277   - }];
278   - }
279   - }
280   -}
281   -
282   -/// Get asset at index 获得下标为index的单个照片
283   -/// if index beyond bounds, return nil in callback 如果索引越界, 在回调中返回 nil
284   -- (void)getAssetFromFetchResult:(id)result atIndex:(NSInteger)index allowPickingVideo:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage completion:(void (^)(TZAssetModel *))completion {
285   - if ([result isKindOfClass:[PHFetchResult class]]) {
286   - PHFetchResult *fetchResult = (PHFetchResult *)result;
287   - PHAsset *asset;
288   - @try {
289   - asset = fetchResult[index];
290   - }
291   - @catch (NSException* e) {
292   - if (completion) completion(nil);
293   - return;
294   - }
295   - TZAssetModel *model = [self assetModelWithAsset:asset allowPickingVideo:allowPickingVideo allowPickingImage:allowPickingImage];
296   - if (completion) completion(model);
297   - } else if ([result isKindOfClass:[ALAssetsGroup class]]) {
298   - ALAssetsGroup *group = (ALAssetsGroup *)result;
299   - if (allowPickingImage && allowPickingVideo) {
300   - [group setAssetsFilter:[ALAssetsFilter allAssets]];
301   - } else if (allowPickingVideo) {
302   - [group setAssetsFilter:[ALAssetsFilter allVideos]];
303   - } else if (allowPickingImage) {
304   - [group setAssetsFilter:[ALAssetsFilter allPhotos]];
305   - }
306   - NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:index];
307   - @try {
308   - [group enumerateAssetsAtIndexes:indexSet options:NSEnumerationConcurrent usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {
309   - if (!result) return;
310   - TZAssetModel *model = [self assetModelWithAsset:result allowPickingVideo:allowPickingVideo allowPickingImage:allowPickingImage];
311   - if (completion) completion(model);
312   - }];
313   - }
314   - @catch (NSException* e) {
315   - if (completion) completion(nil);
316   - }
317   - }
318   -}
319   -
320   -- (TZAssetModel *)assetModelWithAsset:(id)asset allowPickingVideo:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage {
321   - BOOL canSelect = YES;
322   - if ([self.pickerDelegate respondsToSelector:@selector(isAssetCanSelect:)]) {
323   - canSelect = [self.pickerDelegate isAssetCanSelect:asset];
324   - }
325   - if (!canSelect) return nil;
326   -
327   - TZAssetModel *model;
328   - TZAssetModelMediaType type = [self getAssetType:asset];
329   - if ([asset isKindOfClass:[PHAsset class]]) {
330   - if (!allowPickingVideo && type == TZAssetModelMediaTypeVideo) return nil;
331   - if (!allowPickingImage && type == TZAssetModelMediaTypePhoto) return nil;
332   - if (!allowPickingImage && type == TZAssetModelMediaTypePhotoGif) return nil;
333   -
334   - PHAsset *phAsset = (PHAsset *)asset;
335   - if (self.hideWhenCanNotSelect) {
336   - // 过滤掉尺寸不满足要求的图片
337   - if (![self isPhotoSelectableWithAsset:phAsset]) {
338   - return nil;
339   - }
340   - }
341   - NSString *timeLength = type == TZAssetModelMediaTypeVideo ? [NSString stringWithFormat:@"%0.0f",phAsset.duration] : @"";
342   - timeLength = [self getNewTimeFromDurationSecond:timeLength.integerValue];
343   - model = [TZAssetModel modelWithAsset:asset type:type timeLength:timeLength];
344   - } else {
345   - if (!allowPickingVideo){
346   - model = [TZAssetModel modelWithAsset:asset type:type];
347   - return model;
348   - }
349   - /// Allow picking video
350   - if (type == TZAssetModelMediaTypeVideo) {
351   - NSTimeInterval duration = [[asset valueForProperty:ALAssetPropertyDuration] doubleValue];
352   - NSString *timeLength = [NSString stringWithFormat:@"%0.0f",duration];
353   - timeLength = [self getNewTimeFromDurationSecond:timeLength.integerValue];
354   - model = [TZAssetModel modelWithAsset:asset type:type timeLength:timeLength];
355   - } else {
356   - if (self.hideWhenCanNotSelect) {
357   - // 过滤掉尺寸不满足要求的图片
358   - if (![self isPhotoSelectableWithAsset:asset]) {
359   - return nil;
360   - }
361   - }
362   - model = [TZAssetModel modelWithAsset:asset type:type];
363   - }
364   - }
365   - return model;
366   -}
367   -
368   -- (TZAssetModelMediaType)getAssetType:(id)asset {
369   - TZAssetModelMediaType type = TZAssetModelMediaTypePhoto;
370   - if ([asset isKindOfClass:[PHAsset class]]) {
371   - PHAsset *phAsset = (PHAsset *)asset;
372   - if (phAsset.mediaType == PHAssetMediaTypeVideo) type = TZAssetModelMediaTypeVideo;
373   - else if (phAsset.mediaType == PHAssetMediaTypeAudio) type = TZAssetModelMediaTypeAudio;
374   - else if (phAsset.mediaType == PHAssetMediaTypeImage) {
375   - if (@available(iOS 9.1, *)) {
376   - // if (asset.mediaSubtypes == PHAssetMediaSubtypePhotoLive) type = TZAssetModelMediaTypeLivePhoto;
377   - }
378   - // Gif
379   - if ([[phAsset valueForKey:@"filename"] hasSuffix:@"GIF"]) {
380   - type = TZAssetModelMediaTypePhotoGif;
381   - }
382   - }
383   - } else {
384   - if ([[asset valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo]) {
385   - type = TZAssetModelMediaTypeVideo;
386   - }
387   - }
388   - return type;
389   -}
390   -
391   -- (NSString *)getNewTimeFromDurationSecond:(NSInteger)duration {
392   - NSString *newTime;
393   - if (duration < 10) {
394   - newTime = [NSString stringWithFormat:@"0:0%zd",duration];
395   - } else if (duration < 60) {
396   - newTime = [NSString stringWithFormat:@"0:%zd",duration];
397   - } else {
398   - NSInteger min = duration / 60;
399   - NSInteger sec = duration - (min * 60);
400   - if (sec < 10) {
401   - newTime = [NSString stringWithFormat:@"%zd:0%zd",min,sec];
402   - } else {
403   - newTime = [NSString stringWithFormat:@"%zd:%zd",min,sec];
404   - }
405   - }
406   - return newTime;
407   -}
408   -
409   -/// Get photo bytes 获得一组照片的大小
410   -- (void)getPhotosBytesWithArray:(NSArray *)photos completion:(void (^)(NSString *totalBytes))completion {
411   - if (!photos || !photos.count) {
412   - if (completion) completion(@"0B");
413   - return;
414   - }
415   - __block NSInteger dataLength = 0;
416   - __block NSInteger assetCount = 0;
417   - for (NSInteger i = 0; i < photos.count; i++) {
418   - TZAssetModel *model = photos[i];
419   - if ([model.asset isKindOfClass:[PHAsset class]]) {
420   - PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
421   - options.resizeMode = PHImageRequestOptionsResizeModeFast;
422   - options.networkAccessAllowed = YES;
423   - if (model.type == TZAssetModelMediaTypePhotoGif) {
424   - options.version = PHImageRequestOptionsVersionOriginal;
425   - }
426   - [[PHImageManager defaultManager] requestImageDataForAsset:model.asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
427   - if (model.type != TZAssetModelMediaTypeVideo) dataLength += imageData.length;
428   - assetCount ++;
429   - if (assetCount >= photos.count) {
430   - NSString *bytes = [self getBytesFromDataLength:dataLength];
431   - if (completion) completion(bytes);
432   - }
433   - }];
434   - } else if ([model.asset isKindOfClass:[ALAsset class]]) {
435   - ALAssetRepresentation *representation = [model.asset defaultRepresentation];
436   - if (model.type != TZAssetModelMediaTypeVideo) dataLength += (NSInteger)representation.size;
437   - if (i >= photos.count - 1) {
438   - NSString *bytes = [self getBytesFromDataLength:dataLength];
439   - if (completion) completion(bytes);
440   - }
441   - }
442   - }
443   -}
444   -
445   -- (NSString *)getBytesFromDataLength:(NSInteger)dataLength {
446   - NSString *bytes;
447   - if (dataLength >= 0.1 * (1024 * 1024)) {
448   - bytes = [NSString stringWithFormat:@"%0.1fM",dataLength/1024/1024.0];
449   - } else if (dataLength >= 1024) {
450   - bytes = [NSString stringWithFormat:@"%0.0fK",dataLength/1024.0];
451   - } else {
452   - bytes = [NSString stringWithFormat:@"%zdB",dataLength];
453   - }
454   - return bytes;
455   -}
456   -
457   -#pragma mark - Get Photo
458   -
459   -/// Get photo 获得照片本身
460   -- (int32_t)getPhotoWithAsset:(id)asset completion:(void (^)(UIImage *, NSDictionary *, BOOL isDegraded))completion {
461   - CGFloat fullScreenWidth = TZScreenWidth;
462   - if (fullScreenWidth > _photoPreviewMaxWidth) {
463   - fullScreenWidth = _photoPreviewMaxWidth;
464   - }
465   - return [self getPhotoWithAsset:asset photoWidth:fullScreenWidth completion:completion progressHandler:nil networkAccessAllowed:YES];
466   -}
467   -
468   -- (int32_t)getPhotoWithAsset:(id)asset photoWidth:(CGFloat)photoWidth completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion {
469   - return [self getPhotoWithAsset:asset photoWidth:photoWidth completion:completion progressHandler:nil networkAccessAllowed:YES];
470   -}
471   -
472   -- (int32_t)getPhotoWithAsset:(id)asset completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed {
473   - CGFloat fullScreenWidth = TZScreenWidth;
474   - if (fullScreenWidth > _photoPreviewMaxWidth) {
475   - fullScreenWidth = _photoPreviewMaxWidth;
476   - }
477   - return [self getPhotoWithAsset:asset photoWidth:fullScreenWidth completion:completion progressHandler:progressHandler networkAccessAllowed:networkAccessAllowed];
478   -}
479   -
480   -- (int32_t)requestImageDataForAsset:(id)asset completion:(void (^)(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler {
481   - if ([asset isKindOfClass:[PHAsset class]]) {
482   - PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
483   - options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
484   - dispatch_async(dispatch_get_main_queue(), ^{
485   - if (progressHandler) {
486   - progressHandler(progress, error, stop, info);
487   - }
488   - });
489   - };
490   - options.networkAccessAllowed = YES;
491   - options.resizeMode = PHImageRequestOptionsResizeModeFast;
492   - int32_t imageRequestID = [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
493   - if (completion) completion(imageData,dataUTI,orientation,info);
494   - }];
495   - return imageRequestID;
496   - } else if ([asset isKindOfClass:[ALAsset class]]) {
497   - ALAsset *alAsset = (ALAsset *)asset;
498   - dispatch_async(dispatch_get_global_queue(0,0), ^{
499   - ALAssetRepresentation *assetRep = [alAsset defaultRepresentation];
500   - CGImageRef fullScrennImageRef = [assetRep fullScreenImage];
501   - UIImage *fullScrennImage = [UIImage imageWithCGImage:fullScrennImageRef scale:2.0 orientation:UIImageOrientationUp];
502   - dispatch_async(dispatch_get_main_queue(), ^{
503   - if (completion) completion(UIImageJPEGRepresentation(fullScrennImage, 0.83), nil, UIImageOrientationUp, nil);
504   - });
505   - });
506   - }
507   - return 0;
508   -}
509   -
510   -- (int32_t)getPhotoWithAsset:(id)asset photoWidth:(CGFloat)photoWidth completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed {
511   - if ([asset isKindOfClass:[PHAsset class]]) {
512   - CGSize imageSize;
513   - if (photoWidth < TZScreenWidth && photoWidth < _photoPreviewMaxWidth) {
514   - imageSize = AssetGridThumbnailSize;
515   - } else {
516   - PHAsset *phAsset = (PHAsset *)asset;
517   - CGFloat aspectRatio = phAsset.pixelWidth / (CGFloat)phAsset.pixelHeight;
518   - CGFloat pixelWidth = photoWidth * TZScreenScale * 1.5;
519   - // 超宽图片
520   - if (aspectRatio > 1.8) {
521   - pixelWidth = pixelWidth * aspectRatio;
522   - }
523   - // 超高图片
524   - if (aspectRatio < 0.2) {
525   - pixelWidth = pixelWidth * 0.5;
526   - }
527   - CGFloat pixelHeight = pixelWidth / aspectRatio;
528   - imageSize = CGSizeMake(pixelWidth, pixelHeight);
529   - }
530   -
531   - __block UIImage *image;
532   - // 修复获取图片时出现的瞬间内存过高问题
533   - // 下面两行代码,来自hsjcom,他的github是:https://github.com/hsjcom 表示感谢
534   - PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
535   - option.resizeMode = PHImageRequestOptionsResizeModeFast;
536   - int32_t imageRequestID = [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:imageSize contentMode:PHImageContentModeAspectFill options:option resultHandler:^(UIImage *result, NSDictionary *info) {
537   - if (result) {
538   - image = result;
539   - }
540   - BOOL downloadFinined = (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey]);
541   - if (downloadFinined && result) {
542   - result = [self fixOrientation:result];
543   - if (completion) completion(result,info,[[info objectForKey:PHImageResultIsDegradedKey] boolValue]);
544   - }
545   - // Download image from iCloud / 从iCloud下载图片
546   - if ([info objectForKey:PHImageResultIsInCloudKey] && !result && networkAccessAllowed) {
547   - PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
548   - options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
549   - dispatch_async(dispatch_get_main_queue(), ^{
550   - if (progressHandler) {
551   - progressHandler(progress, error, stop, info);
552   - }
553   - });
554   - };
555   - options.networkAccessAllowed = YES;
556   - options.resizeMode = PHImageRequestOptionsResizeModeFast;
557   - [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
558   - UIImage *resultImage = [UIImage imageWithData:imageData scale:0.1];
559   - if (![TZImagePickerConfig sharedInstance].notScaleImage) {
560   - resultImage = [self scaleImage:resultImage toSize:imageSize];
561   - }
562   - if (!resultImage) {
563   - resultImage = image;
564   - }
565   - resultImage = [self fixOrientation:resultImage];
566   - if (completion) completion(resultImage,info,NO);
567   - }];
568   - }
569   - }];
570   - return imageRequestID;
571   - } else if ([asset isKindOfClass:[ALAsset class]]) {
572   - ALAsset *alAsset = (ALAsset *)asset;
573   - dispatch_async(dispatch_get_global_queue(0,0), ^{
574   - CGImageRef thumbnailImageRef = alAsset.thumbnail;
575   - UIImage *thumbnailImage = [UIImage imageWithCGImage:thumbnailImageRef scale:2.0 orientation:UIImageOrientationUp];
576   - dispatch_async(dispatch_get_main_queue(), ^{
577   - if (completion) completion(thumbnailImage,nil,YES);
578   -
579   - if (photoWidth == TZScreenWidth || photoWidth == self->_photoPreviewMaxWidth) {
580   - dispatch_async(dispatch_get_global_queue(0,0), ^{
581   - ALAssetRepresentation *assetRep = [alAsset defaultRepresentation];
582   - CGImageRef fullScrennImageRef = [assetRep fullScreenImage];
583   - UIImage *fullScrennImage = [UIImage imageWithCGImage:fullScrennImageRef scale:2.0 orientation:UIImageOrientationUp];
584   -
585   - dispatch_async(dispatch_get_main_queue(), ^{
586   - if (completion) completion(fullScrennImage,nil,NO);
587   - });
588   - });
589   - }
590   - });
591   - });
592   - }
593   - return 0;
594   -}
595   -
596   -/// Get postImage / 获取封面图
597   -- (void)getPostImageWithAlbumModel:(TZAlbumModel *)model completion:(void (^)(UIImage *))completion {
598   - if (iOS8Later) {
599   - id asset = [model.result lastObject];
600   - if (!self.sortAscendingByModificationDate) {
601   - asset = [model.result firstObject];
602   - }
603   - [[TZImageManager manager] getPhotoWithAsset:asset photoWidth:80 completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
604   - if (completion) completion(photo);
605   - }];
606   - } else {
607   - ALAssetsGroup *group = model.result;
608   - UIImage *postImage = [UIImage imageWithCGImage:group.posterImage];
609   - if (completion) completion(postImage);
610   - }
611   -}
612   -
613   -/// Get Original Photo / 获取原图
614   -- (void)getOriginalPhotoWithAsset:(id)asset completion:(void (^)(UIImage *photo,NSDictionary *info))completion {
615   - [self getOriginalPhotoWithAsset:asset newCompletion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
616   - if (completion) {
617   - completion(photo,info);
618   - }
619   - }];
620   -}
621   -
622   -- (void)getOriginalPhotoWithAsset:(id)asset newCompletion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion {
623   - if ([asset isKindOfClass:[PHAsset class]]) {
624   - PHImageRequestOptions *option = [[PHImageRequestOptions alloc]init];
625   - option.networkAccessAllowed = YES;
626   - option.resizeMode = PHImageRequestOptionsResizeModeFast;
627   - [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:option resultHandler:^(UIImage *result, NSDictionary *info) {
628   - BOOL downloadFinined = (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey]);
629   - if (downloadFinined && result) {
630   - result = [self fixOrientation:result];
631   - BOOL isDegraded = [[info objectForKey:PHImageResultIsDegradedKey] boolValue];
632   - if (completion) completion(result,info,isDegraded);
633   - }
634   - }];
635   - } else if ([asset isKindOfClass:[ALAsset class]]) {
636   - ALAsset *alAsset = (ALAsset *)asset;
637   - ALAssetRepresentation *assetRep = [alAsset defaultRepresentation];
638   -
639   - dispatch_async(dispatch_get_global_queue(0,0), ^{
640   - CGImageRef originalImageRef = [assetRep fullResolutionImage];
641   - UIImage *originalImage = [UIImage imageWithCGImage:originalImageRef scale:1.0 orientation:UIImageOrientationUp];
642   -
643   - dispatch_async(dispatch_get_main_queue(), ^{
644   - if (completion) completion(originalImage,nil,NO);
645   - });
646   - });
647   - }
648   -}
649   -
650   -- (void)getOriginalPhotoDataWithAsset:(id)asset completion:(void (^)(NSData *data,NSDictionary *info,BOOL isDegraded))completion {
651   - [self getOriginalPhotoDataWithAsset:asset progressHandler:nil completion:completion];
652   -}
653   -
654   -- (void)getOriginalPhotoDataWithAsset:(id)asset progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler completion:(void (^)(NSData *data,NSDictionary *info,BOOL isDegraded))completion {
655   - if ([asset isKindOfClass:[PHAsset class]]) {
656   - PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
657   - option.networkAccessAllowed = YES;
658   - if ([[asset valueForKey:@"filename"] hasSuffix:@"GIF"]) {
659   - // if version isn't PHImageRequestOptionsVersionOriginal, the gif may cann't play
660   - option.version = PHImageRequestOptionsVersionOriginal;
661   - }
662   - [option setProgressHandler:progressHandler];
663   - option.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
664   - [[PHImageManager defaultManager] requestImageDataForAsset:asset options:option resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
665   - BOOL downloadFinined = (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey]);
666   - if (downloadFinined && imageData) {
667   - if (completion) completion(imageData,info,NO);
668   - }
669   - }];
670   - } else if ([asset isKindOfClass:[ALAsset class]]) {
671   - ALAsset *alAsset = (ALAsset *)asset;
672   - ALAssetRepresentation *assetRep = [alAsset defaultRepresentation];
673   - Byte *imageBuffer = (Byte *)malloc(assetRep.size);
674   - NSUInteger bufferSize = [assetRep getBytes:imageBuffer fromOffset:0.0 length:assetRep.size error:nil];
675   - NSData *imageData = [NSData dataWithBytesNoCopy:imageBuffer length:bufferSize freeWhenDone:YES];
676   - if (completion) completion(imageData,nil,NO);
677   - }
678   -}
679   -
680   -#pragma mark - Save photo
681   -
682   -- (void)savePhotoWithImage:(UIImage *)image completion:(void (^)(NSError *error))completion {
683   - [self savePhotoWithImage:image location:nil completion:completion];
684   -}
685   -
686   -- (void)savePhotoWithImage:(UIImage *)image location:(CLLocation *)location completion:(void (^)(NSError *error))completion {
687   - if (iOS8Later) {
688   - [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
689   - if (@available(iOS 9, *)) {
690   - NSData *data = UIImageJPEGRepresentation(image, 0.9);
691   - PHAssetResourceCreationOptions *options = [[PHAssetResourceCreationOptions alloc] init];
692   - options.shouldMoveFile = YES;
693   - PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAsset];
694   - [request addResourceWithType:PHAssetResourceTypePhoto data:data options:options];
695   - if (location) {
696   - request.location = location;
697   - }
698   - request.creationDate = [NSDate date];
699   - } else {
700   - PHAssetChangeRequest *request = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
701   - if (location) {
702   - request.location = location;
703   - }
704   - request.creationDate = [NSDate date];
705   - }
706   - } completionHandler:^(BOOL success, NSError *error) {
707   - dispatch_async(dispatch_get_main_queue(), ^{
708   - if (success && completion) {
709   - completion(nil);
710   - } else if (error) {
711   - NSLog(@"保存照片出错:%@",error.localizedDescription);
712   - if (completion) {
713   - completion(error);
714   - }
715   - }
716   - });
717   - }];
718   - } else {
719   - [self.assetLibrary writeImageToSavedPhotosAlbum:image.CGImage orientation:[self orientationFromImage:image] completionBlock:^(NSURL *assetURL, NSError *error) {
720   - if (error) {
721   - NSLog(@"保存图片失败:%@",error.localizedDescription);
722   - if (completion) {
723   - completion(error);
724   - }
725   - } else {
726   - // 多给系统0.5秒的时间,让系统去更新相册数据
727   - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
728   - if (completion) {
729   - completion(nil);
730   - }
731   - });
732   - }
733   - }];
734   - }
735   -}
736   -
737   -#pragma mark - Save video
738   -
739   -- (void)saveVideoWithUrl:(NSURL *)url completion:(void (^)(NSError *error))completion {
740   - [self saveVideoWithUrl:url location:nil completion:completion];
741   -}
742   -
743   -- (void)saveVideoWithUrl:(NSURL *)url location:(CLLocation *)location completion:(void (^)(NSError *error))completion {
744   - if (iOS8Later) {
745   - [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
746   - if (@available(iOS 9, *)) {
747   - PHAssetResourceCreationOptions *options = [[PHAssetResourceCreationOptions alloc] init];
748   - options.shouldMoveFile = YES;
749   - PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAsset];
750   - [request addResourceWithType:PHAssetResourceTypeVideo fileURL:url options:options];
751   - if (location) {
752   - request.location = location;
753   - }
754   - request.creationDate = [NSDate date];
755   - } else {
756   - PHAssetChangeRequest *request = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:url];
757   - if (location) {
758   - request.location = location;
759   - }
760   - request.creationDate = [NSDate date];
761   - }
762   - } completionHandler:^(BOOL success, NSError *error) {
763   - dispatch_async(dispatch_get_main_queue(), ^{
764   - if (success && completion) {
765   - completion(nil);
766   - } else if (error) {
767   - NSLog(@"保存视频出错:%@",error.localizedDescription);
768   - if (completion) {
769   - completion(error);
770   - }
771   - }
772   - });
773   - }];
774   - } else {
775   - [self.assetLibrary writeVideoAtPathToSavedPhotosAlbum:url completionBlock:^(NSURL *assetURL, NSError *error) {
776   - if (error) {
777   - NSLog(@"保存视频出错:%@",error.localizedDescription);
778   - if (completion) {
779   - completion(error);
780   - }
781   - } else {
782   - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
783   - if (completion) {
784   - completion(nil);
785   - }
786   - });
787   - }
788   - }];
789   - }
790   -}
791   -
792   -#pragma mark - Get Video
793   -
794   -/// Get Video / 获取视频
795   -- (void)getVideoWithAsset:(id)asset completion:(void (^)(AVPlayerItem *, NSDictionary *))completion {
796   - [self getVideoWithAsset:asset progressHandler:nil completion:completion];
797   -}
798   -
799   -- (void)getVideoWithAsset:(id)asset progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler completion:(void (^)(AVPlayerItem *, NSDictionary *))completion {
800   - if ([asset isKindOfClass:[PHAsset class]]) {
801   - PHVideoRequestOptions *option = [[PHVideoRequestOptions alloc] init];
802   - option.networkAccessAllowed = YES;
803   - option.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
804   - dispatch_async(dispatch_get_main_queue(), ^{
805   - if (progressHandler) {
806   - progressHandler(progress, error, stop, info);
807   - }
808   - });
809   - };
810   - [[PHImageManager defaultManager] requestPlayerItemForVideo:asset options:option resultHandler:^(AVPlayerItem *playerItem, NSDictionary *info) {
811   - if (completion) completion(playerItem,info);
812   - }];
813   - } else if ([asset isKindOfClass:[ALAsset class]]) {
814   - ALAsset *alAsset = (ALAsset *)asset;
815   - ALAssetRepresentation *defaultRepresentation = [alAsset defaultRepresentation];
816   - NSString *uti = [defaultRepresentation UTI];
817   - NSURL *videoURL = [[asset valueForProperty:ALAssetPropertyURLs] valueForKey:uti];
818   - AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:videoURL];
819   - if (completion && playerItem) completion(playerItem,nil);
820   - }
821   -}
822   -
823   -#pragma mark - Export video
824   -
825   -/// Export Video / 导出视频
826   -- (void)getVideoOutputPathWithAsset:(id)asset success:(void (^)(NSString *outputPath))success failure:(void (^)(NSString *errorMessage, NSError *error))failure {
827   - [self getVideoOutputPathWithAsset:asset presetName:AVAssetExportPreset640x480 success:success failure:failure];
828   -}
829   -
830   -- (void)getVideoOutputPathWithAsset:(id)asset presetName:(NSString *)presetName success:(void (^)(NSString *outputPath))success failure:(void (^)(NSString *errorMessage, NSError *error))failure {
831   - if ([asset isKindOfClass:[PHAsset class]]) {
832   - PHVideoRequestOptions* options = [[PHVideoRequestOptions alloc] init];
833   - options.version = PHVideoRequestOptionsVersionOriginal;
834   - options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
835   - options.networkAccessAllowed = YES;
836   - [[PHImageManager defaultManager] requestAVAssetForVideo:asset options:options resultHandler:^(AVAsset* avasset, AVAudioMix* audioMix, NSDictionary* info){
837   - // NSLog(@"Info:\n%@",info);
838   - AVURLAsset *videoAsset = (AVURLAsset*)avasset;
839   - // NSLog(@"AVAsset URL: %@",myAsset.URL);
840   - [self startExportVideoWithVideoAsset:videoAsset presetName:presetName success:success failure:failure];
841   - }];
842   - } else if ([asset isKindOfClass:[ALAsset class]]) {
843   - NSURL *videoURL =[asset valueForProperty:ALAssetPropertyAssetURL]; // ALAssetPropertyURLs
844   - AVURLAsset *videoAsset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
845   - [self startExportVideoWithVideoAsset:videoAsset presetName:presetName success:success failure:failure];
846   - }
847   -}
848   -
849   -/// Deprecated, Use -getVideoOutputPathWithAsset:failure:success:
850   -- (void)getVideoOutputPathWithAsset:(id)asset completion:(void (^)(NSString *outputPath))completion {
851   - [self getVideoOutputPathWithAsset:asset success:completion failure:nil];
852   -}
853   -
854   -- (void)startExportVideoWithVideoAsset:(AVURLAsset *)videoAsset presetName:(NSString *)presetName success:(void (^)(NSString *outputPath))success failure:(void (^)(NSString *errorMessage, NSError *error))failure {
855   - // Find compatible presets by video asset.
856   - NSArray *presets = [AVAssetExportSession exportPresetsCompatibleWithAsset:videoAsset];
857   -
858   - // Begin to compress video
859   - // Now we just compress to low resolution if it supports
860   - // If you need to upload to the server, but server does't support to upload by streaming,
861   - // You can compress the resolution to lower. Or you can support more higher resolution.
862   - if ([presets containsObject:presetName]) {
863   - AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:videoAsset presetName:presetName];
864   -
865   - NSDateFormatter *formater = [[NSDateFormatter alloc] init];
866   - [formater setDateFormat:@"yyyy-MM-dd-HH:mm:ss-SSS"];
867   -#pragma mark - ADD: 原有逻辑-根据会话id取得path(LXG)
868   - NSString *outputPath = @"";
869   - if (self.outputPath.length <= 0) {
870   - outputPath = [NSHomeDirectory() stringByAppendingFormat:@"/tmp/output-%@.mp4", [formater stringFromDate:[NSDate date]]];
871   - }else {
872   - NSString *filaName = [NSString stringWithFormat:@"output-%@_fileType=videoType.mp4",[formater stringFromDate:[NSDate date]]];
873   - outputPath = [self.outputPath stringByAppendingString:filaName];
874   - }
875   -
876   - NSLog(@"video outputPath = %@",outputPath);
877   -
878   - session.outputURL = [NSURL fileURLWithPath:outputPath];
879   -
880   - // Optimize for network use.
881   - session.shouldOptimizeForNetworkUse = true;
882   -
883   - NSArray *supportedTypeArray = session.supportedFileTypes;
884   - if ([supportedTypeArray containsObject:AVFileTypeMPEG4]) {
885   - session.outputFileType = AVFileTypeMPEG4;
886   - } else if (supportedTypeArray.count == 0) {
887   - if (failure) {
888   - failure(@"该视频类型暂不支持导出", nil);
889   - }
890   - NSLog(@"No supported file types 视频类型暂不支持导出");
891   - return;
892   - } else {
893   - session.outputFileType = [supportedTypeArray objectAtIndex:0];
894   - }
895   -
896   - if (![[NSFileManager defaultManager] fileExistsAtPath:[NSHomeDirectory() stringByAppendingFormat:@"/tmp"]]) {
897   - [[NSFileManager defaultManager] createDirectoryAtPath:[NSHomeDirectory() stringByAppendingFormat:@"/tmp"] withIntermediateDirectories:YES attributes:nil error:nil];
898   - }
899   -
900   - if ([TZImagePickerConfig sharedInstance].needFixComposition) {
901   - AVMutableVideoComposition *videoComposition = [self fixedCompositionWithAsset:videoAsset];
902   - if (videoComposition.renderSize.width) {
903   - // 修正视频转向
904   - session.videoComposition = videoComposition;
905   - }
906   - }
907   -
908   - // Begin to export video to the output path asynchronously.
909   -#pragma mark - ADD: 原有逻辑-会话id置空(LXG)
910   - [session exportAsynchronouslyWithCompletionHandler:^(void) {
911   - dispatch_async(dispatch_get_main_queue(), ^{
912   -
913   - switch (session.status) {
914   - case AVAssetExportSessionStatusUnknown: {
915   - NSLog(@"AVAssetExportSessionStatusUnknown");
916   - } break;
917   - case AVAssetExportSessionStatusWaiting: {
918   - NSLog(@"AVAssetExportSessionStatusWaiting");
919   - } break;
920   - case AVAssetExportSessionStatusExporting: {
921   - NSLog(@"AVAssetExportSessionStatusExporting");
922   - } break;
923   - case AVAssetExportSessionStatusCompleted: {
924   - NSLog(@"AVAssetExportSessionStatusCompleted");
925   - if (success) {
926   - success(outputPath);
927   - }
928   - } break;
929   - case AVAssetExportSessionStatusFailed: {
930   - NSLog(@"AVAssetExportSessionStatusFailed");
931   - if (failure) {
932   - failure(@"视频导出失败", session.error);
933   - }
934   - } break;
935   - case AVAssetExportSessionStatusCancelled: {
936   - NSLog(@"AVAssetExportSessionStatusCancelled");
937   - if (failure) {
938   - failure(@"导出任务已被取消", nil);
939   - }
940   - } break;
941   - default:
942   - NSLog(@"未知错误");
943   - break;
944   - }
945   - });
946   - }];
947   - } else {
948   - if (failure) {
949   - NSString *errorMessage = [NSString stringWithFormat:@"当前设备不支持该预设:%@", presetName];
950   - failure(errorMessage, nil);
951   - }
952   - }
953   -}
954   -
955   -/// Judge is a assets array contain the asset 判断一个assets数组是否包含这个asset
956   -- (BOOL)isAssetsArray:(NSArray *)assets containAsset:(id)asset {
957   - if (iOS8Later) {
958   - return [assets containsObject:asset];
959   - } else {
960   - NSMutableArray *selectedAssetUrls = [NSMutableArray array];
961   - for (ALAsset *asset_item in assets) {
962   - [selectedAssetUrls addObject:[asset_item valueForProperty:ALAssetPropertyURLs]];
963   - }
964   - return [selectedAssetUrls containsObject:[asset valueForProperty:ALAssetPropertyURLs]];
965   - }
966   -}
967   -
968   -- (BOOL)isCameraRollAlbum:(id)metadata {
969   - if ([metadata isKindOfClass:[PHAssetCollection class]]) {
970   - NSString *versionStr = [[UIDevice currentDevice].systemVersion stringByReplacingOccurrencesOfString:@"." withString:@""];
971   - if (versionStr.length <= 1) {
972   - versionStr = [versionStr stringByAppendingString:@"00"];
973   - } else if (versionStr.length <= 2) {
974   - versionStr = [versionStr stringByAppendingString:@"0"];
975   - }
976   - CGFloat version = versionStr.floatValue;
977   - // 目前已知8.0.0 ~ 8.0.2系统,拍照后的图片会保存在最近添加中
978   - if (version >= 800 && version <= 802) {
979   - return ((PHAssetCollection *)metadata).assetCollectionSubtype == PHAssetCollectionSubtypeSmartAlbumRecentlyAdded;
980   - } else {
981   - return ((PHAssetCollection *)metadata).assetCollectionSubtype == PHAssetCollectionSubtypeSmartAlbumUserLibrary;
982   - }
983   - }
984   - if ([metadata isKindOfClass:[ALAssetsGroup class]]) {
985   - ALAssetsGroup *group = metadata;
986   - return ([[group valueForProperty:ALAssetsGroupPropertyType] intValue] == ALAssetsGroupSavedPhotos);
987   - }
988   -
989   - return NO;
990   -}
991   -
992   -- (NSString *)getAssetIdentifier:(id)asset {
993   - if (iOS8Later) {
994   - PHAsset *phAsset = (PHAsset *)asset;
995   - return phAsset.localIdentifier;
996   - } else {
997   - ALAsset *alAsset = (ALAsset *)asset;
998   - NSURL *assetUrl = [alAsset valueForProperty:ALAssetPropertyAssetURL];
999   - return assetUrl.absoluteString;
1000   - }
1001   -}
1002   -
1003   -/// 检查照片大小是否满足最小要求
1004   -- (BOOL)isPhotoSelectableWithAsset:(id)asset {
1005   - CGSize photoSize = [self photoSizeWithAsset:asset];
1006   - if (self.minPhotoWidthSelectable > photoSize.width || self.minPhotoHeightSelectable > photoSize.height) {
1007   - return NO;
1008   - }
1009   - return YES;
1010   -}
1011   -
1012   -- (CGSize)photoSizeWithAsset:(id)asset {
1013   - if (iOS8Later) {
1014   - PHAsset *phAsset = (PHAsset *)asset;
1015   - return CGSizeMake(phAsset.pixelWidth, phAsset.pixelHeight);
1016   - } else {
1017   - ALAsset *alAsset = (ALAsset *)asset;
1018   - return alAsset.defaultRepresentation.dimensions;
1019   - }
1020   -}
1021   -
1022   -#pragma mark - Private Method
1023   -
1024   -- (TZAlbumModel *)modelWithResult:(id)result name:(NSString *)name isCameraRoll:(BOOL)isCameraRoll needFetchAssets:(BOOL)needFetchAssets {
1025   - TZAlbumModel *model = [[TZAlbumModel alloc] init];
1026   - [model setResult:result needFetchAssets:needFetchAssets];
1027   - model.name = name;
1028   - model.isCameraRoll = isCameraRoll;
1029   - if ([result isKindOfClass:[PHFetchResult class]]) {
1030   - PHFetchResult *fetchResult = (PHFetchResult *)result;
1031   - model.count = fetchResult.count;
1032   - } else if ([result isKindOfClass:[ALAssetsGroup class]]) {
1033   - ALAssetsGroup *group = (ALAssetsGroup *)result;
1034   - model.count = [group numberOfAssets];
1035   - }
1036   - return model;
1037   -}
1038   -
1039   -/// 缩放图片至新尺寸
1040   -- (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)size {
1041   - if (image.size.width > size.width) {
1042   - UIGraphicsBeginImageContext(size);
1043   - [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
1044   - UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
1045   - UIGraphicsEndImageContext();
1046   - return newImage;
1047   -
1048   - /* 好像不怎么管用:https://mp.weixin.qq.com/s/CiqMlEIp1Ir2EJSDGgMooQ
1049   - CGFloat maxPixelSize = MAX(size.width, size.height);
1050   - CGImageSourceRef sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef)UIImageJPEGRepresentation(image, 0.9), nil);
1051   - NSDictionary *options = @{(__bridge id)kCGImageSourceCreateThumbnailFromImageAlways:(__bridge id)kCFBooleanTrue,
1052   - (__bridge id)kCGImageSourceThumbnailMaxPixelSize:[NSNumber numberWithFloat:maxPixelSize]
1053   - };
1054   - CGImageRef imageRef = CGImageSourceCreateImageAtIndex(sourceRef, 0, (__bridge CFDictionaryRef)options);
1055   - UIImage *newImage = [UIImage imageWithCGImage:imageRef scale:2 orientation:image.imageOrientation];
1056   - CGImageRelease(imageRef);
1057   - CFRelease(sourceRef);
1058   - return newImage;
1059   - */
1060   - } else {
1061   - return image;
1062   - }
1063   -}
1064   -
1065   -/// 判断asset是否是视频
1066   -- (BOOL)isVideo:(id)asset {
1067   - if (iOS8Later) {
1068   - PHAsset *phAsset = asset;
1069   - return phAsset.mediaType == PHAssetMediaTypeVideo;
1070   - } else {
1071   - ALAsset *alAsset = asset;
1072   - NSString *alAssetType = [[alAsset valueForProperty:ALAssetPropertyType] stringValue];
1073   - return [alAssetType isEqualToString:ALAssetTypeVideo];
1074   - }
1075   -}
1076   -
1077   -- (ALAssetOrientation)orientationFromImage:(UIImage *)image {
1078   - NSInteger orientation = image.imageOrientation;
1079   - return orientation;
1080   -}
1081   -
1082   -/// 获取优化后的视频转向信息
1083   -- (AVMutableVideoComposition *)fixedCompositionWithAsset:(AVAsset *)videoAsset {
1084   - AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
1085   - // 视频转向
1086   - int degrees = [self degressFromVideoFileWithAsset:videoAsset];
1087   - if (degrees != 0) {
1088   - CGAffineTransform translateToCenter;
1089   - CGAffineTransform mixedTransform;
1090   - videoComposition.frameDuration = CMTimeMake(1, 30);
1091   -
1092   - NSArray *tracks = [videoAsset tracksWithMediaType:AVMediaTypeVideo];
1093   - AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
1094   -
1095   - AVMutableVideoCompositionInstruction *roateInstruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
1096   - roateInstruction.timeRange = CMTimeRangeMake(kCMTimeZero, [videoAsset duration]);
1097   - AVMutableVideoCompositionLayerInstruction *roateLayerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:videoTrack];
1098   -
1099   - if (degrees == 90) {
1100   - // 顺时针旋转90°
1101   - translateToCenter = CGAffineTransformMakeTranslation(videoTrack.naturalSize.height, 0.0);
1102   - mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI_2);
1103   - videoComposition.renderSize = CGSizeMake(videoTrack.naturalSize.height,videoTrack.naturalSize.width);
1104   - [roateLayerInstruction setTransform:mixedTransform atTime:kCMTimeZero];
1105   - } else if(degrees == 180){
1106   - // 顺时针旋转180°
1107   - translateToCenter = CGAffineTransformMakeTranslation(videoTrack.naturalSize.width, videoTrack.naturalSize.height);
1108   - mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI);
1109   - videoComposition.renderSize = CGSizeMake(videoTrack.naturalSize.width,videoTrack.naturalSize.height);
1110   - [roateLayerInstruction setTransform:mixedTransform atTime:kCMTimeZero];
1111   - } else if(degrees == 270){
1112   - // 顺时针旋转270°
1113   - translateToCenter = CGAffineTransformMakeTranslation(0.0, videoTrack.naturalSize.width);
1114   - mixedTransform = CGAffineTransformRotate(translateToCenter,M_PI_2*3.0);
1115   - videoComposition.renderSize = CGSizeMake(videoTrack.naturalSize.height,videoTrack.naturalSize.width);
1116   - [roateLayerInstruction setTransform:mixedTransform atTime:kCMTimeZero];
1117   - }
1118   -
1119   - roateInstruction.layerInstructions = @[roateLayerInstruction];
1120   - // 加入视频方向信息
1121   - videoComposition.instructions = @[roateInstruction];
1122   - }
1123   - return videoComposition;
1124   -}
1125   -
1126   -/// 获取视频角度
1127   -- (int)degressFromVideoFileWithAsset:(AVAsset *)asset {
1128   - int degress = 0;
1129   - NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeVideo];
1130   - if([tracks count] > 0) {
1131   - AVAssetTrack *videoTrack = [tracks objectAtIndex:0];
1132   - CGAffineTransform t = videoTrack.preferredTransform;
1133   - if(t.a == 0 && t.b == 1.0 && t.c == -1.0 && t.d == 0){
1134   - // Portrait
1135   - degress = 90;
1136   - } else if(t.a == 0 && t.b == -1.0 && t.c == 1.0 && t.d == 0){
1137   - // PortraitUpsideDown
1138   - degress = 270;
1139   - } else if(t.a == 1.0 && t.b == 0 && t.c == 0 && t.d == 1.0){
1140   - // LandscapeRight
1141   - degress = 0;
1142   - } else if(t.a == -1.0 && t.b == 0 && t.c == 0 && t.d == -1.0){
1143   - // LandscapeLeft
1144   - degress = 180;
1145   - }
1146   - }
1147   - return degress;
1148   -}
1149   -
1150   -/// 修正图片转向
1151   -- (UIImage *)fixOrientation:(UIImage *)aImage {
1152   - if (!self.shouldFixOrientation) return aImage;
1153   -
1154   - // No-op if the orientation is already correct
1155   - if (aImage.imageOrientation == UIImageOrientationUp)
1156   - return aImage;
1157   -
1158   - // We need to calculate the proper transformation to make the image upright.
1159   - // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
1160   - CGAffineTransform transform = CGAffineTransformIdentity;
1161   -
1162   - switch (aImage.imageOrientation) {
1163   - case UIImageOrientationDown:
1164   - case UIImageOrientationDownMirrored:
1165   - transform = CGAffineTransformTranslate(transform, aImage.size.width, aImage.size.height);
1166   - transform = CGAffineTransformRotate(transform, M_PI);
1167   - break;
1168   -
1169   - case UIImageOrientationLeft:
1170   - case UIImageOrientationLeftMirrored:
1171   - transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
1172   - transform = CGAffineTransformRotate(transform, M_PI_2);
1173   - break;
1174   -
1175   - case UIImageOrientationRight:
1176   - case UIImageOrientationRightMirrored:
1177   - transform = CGAffineTransformTranslate(transform, 0, aImage.size.height);
1178   - transform = CGAffineTransformRotate(transform, -M_PI_2);
1179   - break;
1180   - default:
1181   - break;
1182   - }
1183   -
1184   - switch (aImage.imageOrientation) {
1185   - case UIImageOrientationUpMirrored:
1186   - case UIImageOrientationDownMirrored:
1187   - transform = CGAffineTransformTranslate(transform, aImage.size.width, 0);
1188   - transform = CGAffineTransformScale(transform, -1, 1);
1189   - break;
1190   -
1191   - case UIImageOrientationLeftMirrored:
1192   - case UIImageOrientationRightMirrored:
1193   - transform = CGAffineTransformTranslate(transform, aImage.size.height, 0);
1194   - transform = CGAffineTransformScale(transform, -1, 1);
1195   - break;
1196   - default:
1197   - break;
1198   - }
1199   -
1200   - // Now we draw the underlying CGImage into a new context, applying the transform
1201   - // calculated above.
1202   - CGContextRef ctx = CGBitmapContextCreate(NULL, aImage.size.width, aImage.size.height,
1203   - CGImageGetBitsPerComponent(aImage.CGImage), 0,
1204   - CGImageGetColorSpace(aImage.CGImage),
1205   - CGImageGetBitmapInfo(aImage.CGImage));
1206   - CGContextConcatCTM(ctx, transform);
1207   - switch (aImage.imageOrientation) {
1208   - case UIImageOrientationLeft:
1209   - case UIImageOrientationLeftMirrored:
1210   - case UIImageOrientationRight:
1211   - case UIImageOrientationRightMirrored:
1212   - // Grr...
1213   - CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.height,aImage.size.width), aImage.CGImage);
1214   - break;
1215   -
1216   - default:
1217   - CGContextDrawImage(ctx, CGRectMake(0,0,aImage.size.width,aImage.size.height), aImage.CGImage);
1218   - break;
1219   - }
1220   -
1221   - // And now we just create a new UIImage from the drawing context
1222   - CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
1223   - UIImage *img = [UIImage imageWithCGImage:cgimg];
1224   - CGContextRelease(ctx);
1225   - CGImageRelease(cgimg);
1226   - return img;
1227   -}
1228   -
1229   -#pragma clang diagnostic pop
1230   -
1231   -@end
1232   -
1233   -
1234   -//@implementation TZSortDescriptor
1235   -//
1236   -//- (id)reversedSortDescriptor {
1237   -// return [NSNumber numberWithBool:![TZImageManager manager].sortAscendingByModificationDate];
1238   -//}
1239   -//
1240   -//@end
CNLiveImagePickerController/TZImagePickerController.bundle/MMVideoPreviewPlay@2x.png deleted 100755 → 0

3.56 KB

CNLiveImagePickerController/TZImagePickerController.bundle/MMVideoPreviewPlayHL@2x.png deleted 100755 → 0

3.56 KB

CNLiveImagePickerController/TZImagePickerController.bundle/Root.plist deleted 100755 → 0
1   -<?xml version="1.0" encoding="UTF-8"?>
2   -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3   -<plist version="1.0">
4   -<dict>
5   - <key>StringsTable</key>
6   - <string>Root</string>
7   - <key>PreferenceSpecifiers</key>
8   - <array>
9   - <dict>
10   - <key>Type</key>
11   - <string>PSGroupSpecifier</string>
12   - <key>Title</key>
13   - <string>Group</string>
14   - </dict>
15   - <dict>
16   - <key>Type</key>
17   - <string>PSTextFieldSpecifier</string>
18   - <key>Title</key>
19   - <string>Name</string>
20   - <key>Key</key>
21   - <string>name_preference</string>
22   - <key>DefaultValue</key>
23   - <string></string>
24   - <key>IsSecure</key>
25   - <false/>
26   - <key>KeyboardType</key>
27   - <string>Alphabet</string>
28   - <key>AutocapitalizationType</key>
29   - <string>None</string>
30   - <key>AutocorrectionType</key>
31   - <string>No</string>
32   - </dict>
33   - <dict>
34   - <key>Type</key>
35   - <string>PSToggleSwitchSpecifier</string>
36   - <key>Title</key>
37   - <string>Enabled</string>
38   - <key>Key</key>
39   - <string>enabled_preference</string>
40   - <key>DefaultValue</key>
41   - <true/>
42   - </dict>
43   - <dict>
44   - <key>Type</key>
45   - <string>PSSliderSpecifier</string>
46   - <key>Key</key>
47   - <string>slider_preference</string>
48   - <key>DefaultValue</key>
49   - <real>0.5</real>
50   - <key>MinimumValue</key>
51   - <integer>0</integer>
52   - <key>MaximumValue</key>
53   - <integer>1</integer>
54   - <key>MinimumValueImage</key>
55   - <string></string>
56   - <key>MaximumValueImage</key>
57   - <string></string>
58   - </dict>
59   - </array>
60   -</dict>
61   -</plist>
CNLiveImagePickerController/TZImagePickerController.bundle/VideoSendIcon@2x.png deleted 100755 → 0

223 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/en.lproj/Localizable.strings deleted 100755 → 0
1 1 Binary files a/CNLiveImagePickerController/TZImagePickerController.bundle/en.lproj/Localizable.strings and /dev/null differ
... ...
CNLiveImagePickerController/TZImagePickerController.bundle/fb_quxiao@2x.png deleted 100755 → 0

1.16 KB

CNLiveImagePickerController/TZImagePickerController.bundle/navi_back@2x.png deleted 100755 → 0

116 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/ph_select@2x.png deleted 100755 → 0

1.31 KB

CNLiveImagePickerController/TZImagePickerController.bundle/ph_unselect@2x.png deleted 100755 → 0

902 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/photo_cell_normal.png deleted 100644 → 0

641 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/photo_cell_normal@2x.png deleted 100644 → 0

1.35 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photo_cell_normal@3x.png deleted 100644 → 0

2.57 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photo_def_photoPickerVc@2x.png deleted 100755 → 0

1.13 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photo_def_previewVc@2x.png deleted 100755 → 0

1.13 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photo_number_icon@2x.png deleted 100755 → 0

501 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_back.png deleted 100644 → 0

234 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_back@2x.png deleted 100644 → 0

384 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_back@3x.png deleted 100644 → 0

726 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_def@2x.png deleted 100755 → 0

1.56 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_nor.png deleted 100644 → 0

1.04 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_nor@2x.png deleted 100644 → 0

2.12 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_nor@3x.png deleted 100644 → 0

6.27 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_normal.png deleted 100644 → 0

453 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_normal@2x.png deleted 100644 → 0

902 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_normal@3x.png deleted 100644 → 0

1.77 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_sel@2x.png deleted 100755 → 0

620 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_select.png deleted 100644 → 0

713 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_select@2x.png deleted 100644 → 0

1.31 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photo_original_select@3x.png deleted 100644 → 0

3.56 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photo_sel_photoPickerVc@2x.png deleted 100755 → 0

1006 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/photo_sel_previewVc@2x.png deleted 100755 → 0

1.16 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photoback.png deleted 100644 → 0

1.01 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photoback@2x.png deleted 100644 → 0

1.16 KB

CNLiveImagePickerController/TZImagePickerController.bundle/photoback@3x.png deleted 100644 → 0

1.23 KB

CNLiveImagePickerController/TZImagePickerController.bundle/preview_number_icon@2x.png deleted 100755 → 0

501 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/preview_original_def@2x.png deleted 100755 → 0

392 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/takePicture80@2x.png deleted 100755 → 0

1.25 KB

CNLiveImagePickerController/TZImagePickerController.bundle/takePicture@2x.png deleted 100755 → 0

2.98 KB

CNLiveImagePickerController/TZImagePickerController.bundle/upload_selection1@2x.png deleted 100755 → 0

1.35 KB

CNLiveImagePickerController/TZImagePickerController.bundle/vi.lproj/Localizable.strings deleted 100755 → 0
1   -"OK" = "Xác nhận";
2   -"Back" = "Quay lại";
3   -"Done" = "Hoàn thành";
4   -"Sorry" = "Xin lỗi";
5   -"Cancel" = "Hủy";
6   -"Setting" = "Cài đặt";
7   -"Photos" = "Hình";
8   -"Videos" = "Clip";
9   -"Preview" = "Xem trước";
10   -"Full image" = "Hình gốc";
11   -"Processing..." = "Đang xử lý...";
12   -"Can not use camera" = "Máy chụp hình không khả dụng";
13   -"Synchronizing photos from iCloud" = "Đang đồng bộ hình ảnh từ ICloud";
14   -"Can not choose both video and photo" = "Trong lúc chọn hình ảnh không cùng lúc chọn video";
15   -"Can not choose both photo and GIF" = "Trong lúc chọn hình ảnh không cùng lúc chọn hình GIF";
16   -"Select the video when in multi state, we will handle the video as a photo" = "Chọn hình ảnh cùng video, video sẽ bị mặc nhận thành hình ảnh và gửi đi.";
17   -"Can not jump to the privacy settings page, please go to the settings page by self, thank you" = "Không thể chuyển tự động qua trang cài đặt riêng tư, bạn hãy thoát ra cà điều chỉnh lại, cám ơn bạn.";
18   -
19   -"Select a maximum of %zd photos" = "Bạn chỉ được chọn nhiều nhất %zd tấm hình";
20   -"Select a minimum of %zd photos" = "Chọn ít nhất %zd tấm hình";
21   -"Allow %@ to access your album in \"Settings -> Privacy -> Photos\"" = "Vui lòng tại mục iPhone \" Cài đặt – quyền riêng tư - Ảnh\" mở quyền cho phép %@ truy cập ảnh.";
22   -"Please allow %@ to access your camera in \"Settings -> Privacy -> Camera\"" = "Vui lòng tại mục iPhone \" Cài đặt – quyền riêng tư - Ảnh\" mở quyền cho phép %@ truy cập máy ảnh";
CNLiveImagePickerController/TZImagePickerController.bundle/video_edit_left@2x.png deleted 100644 → 0

203 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/video_edit_left@3x.png deleted 100644 → 0

514 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/video_edit_right@2x.png deleted 100644 → 0

208 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/video_edit_right@3x.png deleted 100644 → 0

502 Bytes

CNLiveImagePickerController/TZImagePickerController.bundle/zh-Hans.lproj/Localizable.strings deleted 100755 → 0
1 1 Binary files a/CNLiveImagePickerController/TZImagePickerController.bundle/zh-Hans.lproj/Localizable.strings and /dev/null differ
... ...
CNLiveImagePickerController/TZImagePickerController.bundle/zh-Hant.lproj/Localizable.strings deleted 100755 → 0
1 1 Binary files a/CNLiveImagePickerController/TZImagePickerController.bundle/zh-Hant.lproj/Localizable.strings and /dev/null differ
... ...
CNLiveImagePickerController/TZImagePickerController.h deleted 100755 → 0
1   -//
2   -// TZImagePickerController.h
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 15/12/24.
6   -// Copyright © 2015年 谭真. All rights reserved.
7   -// version 2.2.6 - 2018.08.21
8   -// 更多信息,请前往项目的github地址:https://github.com/banchichen/TZImagePickerController
9   -
10   -/*
11   - 经过测试,比起xib的方式,把TZAssetCell改用纯代码的方式来写,滑动帧数明显提高了(约提高10帧左右)
12   -
13   - 最初发现这个问题并修复的是@小鱼周凌宇同学,她的博客地址: http://zhoulingyu.com/
14   - 表示感谢~
15   -
16   - 原来xib确实会导致性能问题啊...大家也要注意了...
17   - */
18   -
19   -#import <UIKit/UIKit.h>
20   -#import "TZAssetModel.h"
21   -#import "NSBundle+TZImagePicker.h"
22   -#import "TZImageManager.h"
23   -#import "TZVideoPlayerController.h"
24   -#import "TZGifPhotoPreviewController.h"
25   -#import "TZLocationManager.h"
26   -#import "TZPhotoPreviewController.h"
27   -
28   -#define iOS7Later ([UIDevice currentDevice].systemVersion.floatValue >= 7.0f)
29   -#define iOS8Later ([UIDevice currentDevice].systemVersion.floatValue >= 8.0f)
30   -///
31   -#define iOS9Later ([UIDevice currentDevice].systemVersion.floatValue >= 9.0f)
32   -#define iOS9_1Later ([UIDevice currentDevice].systemVersion.floatValue >= 9.1f)
33   -
34   -@class TZAlbumCell, TZAssetCell;
35   -@protocol TZImagePickerControllerDelegate;
36   -@interface TZImagePickerController : UINavigationController
37   -
38   -#pragma mark -
39   -/// Use this init method / 用这个初始化方法
40   -- (instancetype)initWithMaxImagesCount:(NSInteger)maxImagesCount delegate:(id<TZImagePickerControllerDelegate>)delegate;
41   -- (instancetype)initWithMaxImagesCount:(NSInteger)maxImagesCount columnNumber:(NSInteger)columnNumber delegate:(id<TZImagePickerControllerDelegate>)delegate;
42   -- (instancetype)initWithMaxImagesCount:(NSInteger)maxImagesCount columnNumber:(NSInteger)columnNumber delegate:(id<TZImagePickerControllerDelegate>)delegate pushPhotoPickerVc:(BOOL)pushPhotoPickerVc;
43   -/// This init method just for previewing photos / 用这个初始化方法以预览图片
44   -- (instancetype)initWithSelectedAssets:(NSMutableArray *)selectedAssets selectedPhotos:(NSMutableArray *)selectedPhotos index:(NSInteger)index;
45   -/// This init method for crop photo / 用这个初始化方法以裁剪图片
46   -- (instancetype)initCropTypeWithAsset:(id)asset photo:(UIImage *)photo completion:(void (^)(UIImage *cropImage,id asset))completion;
47   -
48   -#pragma mark -
49   -
50   -#pragma mark - ADD:视频编辑(LXG)
51   -///**
52   -// 是否允许编辑视频,选择一张时候才允许编辑,默认NO
53   -// */
54   -//@property (nonatomic, assign) BOOL allowEditVideo;
55   -
56   -/**
57   - 编辑视频时最大裁剪时间,单位:秒,默认10s 且最低10s
58   -
59   - @discussion 当该参数为10s时,所选视频时长必须大于等于10s才允许进行编辑
60   - */
61   -@property (nonatomic, assign) NSInteger maxEditVideoTime;
62   -
63   -/**
64   - 允许选择视频的最大时长,单位:秒, 默认 120s
65   - */
66   -@property (nonatomic, assign) NSInteger maxVideoDuration;
67   -
68   -/// Default is 9 / 默认最大可选9张图片
69   -@property (nonatomic, assign) NSInteger maxImagesCount;
70   -
71   -/// The minimum count photos user must pick, Default is 0
72   -/// 最小照片必选张数,默认是0
73   -@property (nonatomic, assign) NSInteger minImagesCount;
74   -
75   -/// Always enale the done button, not require minimum 1 photo be picked
76   -/// 让完成按钮一直可以点击,无须最少选择一张图片
77   -@property (nonatomic, assign) BOOL alwaysEnableDoneBtn;
78   -
79   -/// Sort photos ascending by modificationDate,Default is YES
80   -/// 对照片排序,按修改时间升序,默认是YES。如果设置为NO,最新的照片会显示在最前面,内部的拍照按钮会排在第一个
81   -@property (nonatomic, assign) BOOL sortAscendingByModificationDate;
82   -
83   -/// The pixel width of output image, Default is 828px / 导出图片的宽度,默认828像素宽
84   -@property (nonatomic, assign) CGFloat photoWidth;
85   -
86   -/// Default is 600px / 默认600像素宽
87   -@property (nonatomic, assign) CGFloat photoPreviewMaxWidth;
88   -
89   -/// Default is 15, While fetching photo, HUD will dismiss automatic if timeout;
90   -/// 超时时间,默认为15秒,当取图片时间超过15秒还没有取成功时,会自动dismiss HUD;
91   -@property (nonatomic, assign) NSInteger timeout;
92   -
93   -/// Default is YES, if set NO, the original photo button will hide. user can't picking original photo.
94   -/// 默认为YES,如果设置为NO,原图按钮将隐藏,用户不能选择发送原图
95   -@property (nonatomic, assign) BOOL allowPickingOriginalPhoto;
96   -
97   -/// Default is YES, if set NO, user can't picking video.
98   -/// 默认为YES,如果设置为NO,用户将不能选择视频
99   -@property (nonatomic, assign) BOOL allowPickingVideo;
100   -/// Default is NO / 默认为NO,为YES时可以多选视频/gif/图片,和照片共享最大可选张数maxImagesCount的限制
101   -@property (nonatomic, assign) BOOL allowPickingMultipleVideo;
102   -
103   -/// Default is NO, if set YES, user can picking gif image.
104   -/// 默认为NO,如果设置为YES,用户可以选择gif图片
105   -@property (nonatomic, assign) BOOL allowPickingGif;
106   -
107   -/// Default is YES, if set NO, user can't picking image.
108   -/// 默认为YES,如果设置为NO,用户将不能选择发送图片
109   -@property (nonatomic, assign) BOOL allowPickingImage;
110   -
111   -/// Default is YES, if set NO, user can't take picture.
112   -/// 默认为YES,如果设置为NO, 用户将不能拍摄照片
113   -@property (nonatomic, assign) BOOL allowTakePicture;
114   -@property (nonatomic, assign) BOOL allowCameraLocation;
115   -
116   -/// Default is YES, if set NO, user can't take video.
117   -/// 默认为YES,如果设置为NO, 用户将不能拍摄视频
118   -@property(nonatomic, assign) BOOL allowTakeVideo;
119   -/// Default value is 10 minutes / 视频最大拍摄时间,默认是10分钟,单位是秒
120   -@property (assign, nonatomic) NSTimeInterval videoMaximumDuration;
121   -/// Customizing UIImagePickerController's other properties, such as videoQuality / 定制UIImagePickerController的其它属性,比如视频拍摄质量videoQuality
122   -@property (nonatomic, copy) void(^uiImagePickerControllerSettingBlock)(UIImagePickerController *imagePickerController);
123   -
124   -/// 首选语言,如果设置了就用该语言,不设则取当前系统语言。
125   -/// 由于目前只支持中文、繁体中文、英文、越南语。故该属性只支持zh-Hans、zh-Hant、en、vi四种值,其余值无效。
126   -@property (copy, nonatomic) NSString *preferredLanguage;
127   -
128   -/// 语言bundle,preferredLanguage变化时languageBundle会变化
129   -/// 可通过手动设置bundle,让选择器支持新的的语言(需要在设置preferredLanguage后设置languageBundle)。欢迎提交PR把语言文件提交上来~
130   -@property (strong, nonatomic) NSBundle *languageBundle;
131   -
132   -/// Default is YES, if set NO, user can't preview photo.
133   -/// 默认为YES,如果设置为NO,预览按钮将隐藏,用户将不能去预览照片
134   -@property (nonatomic, assign) BOOL allowPreview;
135   -
136   -/// Default is YES, if set NO, the picker don't dismiss itself.
137   -/// 默认为YES,如果设置为NO, 选择器将不会自己dismiss
138   -@property(nonatomic, assign) BOOL autoDismiss;
139   -
140   -/// Default is NO, if set YES, in the delegate method the photos and infos will be nil, only assets hava value.
141   -/// 默认为NO,如果设置为YES,代理方法里photos和infos会是nil,只返回assets
142   -@property (assign, nonatomic) BOOL onlyReturnAsset;
143   -
144   -/// Default is NO, if set YES, will show the image's selected index.
145   -/// 默认为NO,如果设置为YES,会显示照片的选中序号
146   -@property (assign, nonatomic) BOOL showSelectedIndex;
147   -
148   -/// Default is NO, if set YES, when selected photos's count up to maxImagesCount, other photo will show float layer what's color is cannotSelectLayerColor.
149   -/// 默认是NO,如果设置为YES,当照片选择张数达到maxImagesCount时,其它照片会显示颜色为cannotSelectLayerColor的浮层
150   -@property (assign, nonatomic) BOOL showPhotoCannotSelectLayer;
151   -/// Default is white color with 0.8 alpha;
152   -@property (strong, nonatomic) UIColor *cannotSelectLayerColor;
153   -
154   -/// Default is No, if set YES, the result photo will not be scaled to photoWidth pixel width. The photoWidth default is 828px
155   -/// 默认是NO,如果设置为YES,内部不会缩放图片到photoWidth像素宽
156   -@property (assign, nonatomic) BOOL notScaleImage;
157   -
158   -/// 默认是NO,如果设置为YES,导出视频时会修正转向(慎重设为YES,可能导致部分安卓下拍的视频导出失败)
159   -@property (assign, nonatomic) BOOL needFixComposition;
160   -
161   -/// The photos user have selected
162   -/// 用户选中过的图片数组
163   -@property (nonatomic, strong) NSMutableArray *selectedAssets;
164   -@property (nonatomic, strong) NSMutableArray<TZAssetModel *> *selectedModels;
165   -@property (nonatomic, strong) NSMutableArray *selectedAssetIds;
166   -- (void)addSelectedModel:(TZAssetModel *)model;
167   -- (void)removeSelectedModel:(TZAssetModel *)model;
168   -
169   -/// Minimum selectable photo width, Default is 0
170   -/// 最小可选中的图片宽度,默认是0,小于这个宽度的图片不可选中
171   -@property (nonatomic, assign) NSInteger minPhotoWidthSelectable;
172   -@property (nonatomic, assign) NSInteger minPhotoHeightSelectable;
173   -/// Hide the photo what can not be selected, Default is NO
174   -/// 隐藏不可以选中的图片,默认是NO,不推荐将其设置为YES
175   -@property (nonatomic, assign) BOOL hideWhenCanNotSelect;
176   -/// Deprecated, Use statusBarStyle (顶部statusBar 是否为系统默认的黑色,默认为NO)
177   -@property (nonatomic, assign) BOOL isStatusBarDefault __attribute__((deprecated("Use -statusBarStyle.")));
178   -/// statusBar的样式,默认为UIStatusBarStyleLightContent
179   -@property (assign, nonatomic) UIStatusBarStyle statusBarStyle;
180   -
181   -#pragma mark -
182   -/// Single selection mode, valid when maxImagesCount = 1
183   -/// 单选模式,maxImagesCount为1时才生效
184   -@property (nonatomic, assign) BOOL showSelectBtn; ///< 在单选模式下,照片列表页中,显示选择按钮,默认为NO
185   -@property (nonatomic, assign) BOOL allowCrop; ///< 允许裁剪,默认为YES,showSelectBtn为NO才生效
186   -@property (nonatomic, assign) CGRect cropRect; ///< 裁剪框的尺寸
187   -@property (nonatomic, assign) CGRect cropRectPortrait; ///< 裁剪框的尺寸(竖屏)
188   -@property (nonatomic, assign) CGRect cropRectLandscape; ///< 裁剪框的尺寸(横屏)
189   -@property (nonatomic, assign) BOOL needCircleCrop; ///< 需要圆形裁剪框
190   -@property (nonatomic, assign) NSInteger circleCropRadius; ///< 圆形裁剪框半径大小
191   -@property (nonatomic, copy) void (^cropViewSettingBlock)(UIView *cropView); ///< 自定义裁剪框的其他属性
192   -@property (nonatomic, copy) void (^navLeftBarButtonSettingBlock)(UIButton *leftButton); ///< 自定义返回按钮样式及其属性
193   -
194   -/// 【自定义各页面/组件的样式】在界面初始化/组件setModel完成后调用,允许外界修改样式等
195   -@property (nonatomic, copy) void (^photoPickerPageUIConfigBlock)(UICollectionView *collectionView, UIView *bottomToolBar, UIButton *previewButton, UIButton *originalPhotoButton, UILabel *originalPhotoLabel, UIButton *doneButton, UIImageView *numberImageView, UILabel *numberLabel, UIView *divideLine);
196   -@property (nonatomic, copy) void (^photoPreviewPageUIConfigBlock)(UICollectionView *collectionView, UIView *naviBar, UIButton *backButton, UIButton *selectButton, UILabel *indexLabel, UIView *toolBar, UIButton *originalPhotoButton, UILabel *originalPhotoLabel, UIButton *doneButton, UIImageView *numberImageView, UILabel *numberLabel);
197   -@property (nonatomic, copy) void (^videoPreviewPageUIConfigBlock)(UIButton *playButton, UIView *toolBar, UIButton *doneButton);
198   -@property (nonatomic, copy) void (^gifPreviewPageUIConfigBlock)(UIView *toolBar, UIButton *doneButton);
199   -@property (nonatomic, copy) void (^assetCellDidSetModelBlock)(TZAssetCell *cell, UIImageView *imageView, UIImageView *selectImageView, UILabel *indexLabel, UIView *bottomView, UILabel *timeLength, UIImageView *videoImgView);
200   -@property (nonatomic, copy) void (^albumCellDidSetModelBlock)(TZAlbumCell *cell, UIImageView *posterImageView, UILabel *titleLabel);
201   -/// 【自定义各页面/组件的frame】在界面viewDidLayoutSubviews/组件layoutSubviews后调用,允许外界修改frame等
202   -@property (nonatomic, copy) void (^photoPickerPageDidLayoutSubviewsBlock)(UICollectionView *collectionView, UIView *bottomToolBar, UIButton *previewButton, UIButton *originalPhotoButton, UILabel *originalPhotoLabel, UIButton *doneButton, UIImageView *numberImageView, UILabel *numberLabel, UIView *divideLine);
203   -@property (nonatomic, copy) void (^photoPreviewPageDidLayoutSubviewsBlock)(UICollectionView *collectionView, UIView *naviBar, UIButton *backButton, UIButton *selectButton, UILabel *indexLabel, UIView *toolBar, UIButton *originalPhotoButton, UILabel *originalPhotoLabel, UIButton *doneButton, UIImageView *numberImageView, UILabel *numberLabel);
204   -@property (nonatomic, copy) void (^videoPreviewPageDidLayoutSubviewsBlock)(UIButton *playButton, UIView *toolBar, UIButton *doneButton);
205   -@property (nonatomic, copy) void (^gifPreviewPageDidLayoutSubviewsBlock)(UIView *toolBar, UIButton *doneButton);
206   -@property (nonatomic, copy) void (^assetCellDidLayoutSubviewsBlock)(TZAssetCell *cell, UIImageView *imageView, UIImageView *selectImageView, UILabel *indexLabel, UIView *bottomView, UILabel *timeLength, UIImageView *videoImgView);
207   -@property (nonatomic, copy) void (^albumCellDidLayoutSubviewsBlock)(TZAlbumCell *cell, UIImageView *posterImageView, UILabel *titleLabel);
208   -
209   -#pragma mark -
210   -- (id)showAlertWithTitle:(NSString *)title;
211   -- (void)hideAlertView:(id)alertView;
212   -- (void)showProgressHUD;
213   -- (void)hideProgressHUD;
214   -@property (nonatomic, assign) BOOL isSelectOriginalPhoto;
215   -@property (assign, nonatomic) BOOL needShowStatusBar;
216   -
217   -#pragma mark -
218   -@property (nonatomic, copy) NSString *takePictureImageName __attribute__((deprecated("Use -takePictureImage.")));
219   -@property (nonatomic, copy) NSString *photoSelImageName __attribute__((deprecated("Use -photoSelImage.")));
220   -@property (nonatomic, copy) NSString *photoDefImageName __attribute__((deprecated("Use -photoDefImage.")));
221   -@property (nonatomic, copy) NSString *photoOriginSelImageName __attribute__((deprecated("Use -photoOriginSelImage.")));
222   -@property (nonatomic, copy) NSString *photoOriginDefImageName __attribute__((deprecated("Use -photoOriginDefImage.")));
223   -@property (nonatomic, copy) NSString *photoPreviewOriginDefImageName __attribute__((deprecated("Use -photoPreviewOriginDefImage.")));
224   -@property (nonatomic, copy) NSString *photoNumberIconImageName __attribute__((deprecated("Use -photoNumberIconImage.")));
225   -@property (nonatomic, strong) UIImage *takePictureImage;
226   -@property (nonatomic, strong) UIImage *photoSelImage;
227   -@property (nonatomic, strong) UIImage *photoDefImage;
228   -@property (nonatomic, strong) UIImage *photoOriginSelImage;
229   -@property (nonatomic, strong) UIImage *photoOriginDefImage;
230   -@property (nonatomic, strong) UIImage *photoPreviewOriginDefImage;
231   -@property (nonatomic, strong) UIImage *photoNumberIconImage;
232   -
233   -#pragma mark -
234   -/// Appearance / 外观颜色 + 按钮文字
235   -@property (nonatomic, strong) UIColor *oKButtonTitleColorNormal;
236   -@property (nonatomic, strong) UIColor *oKButtonTitleColorDisabled;
237   -@property (nonatomic, strong) UIColor *naviBgColor;
238   -@property (nonatomic, strong) UIColor *naviTitleColor;
239   -@property (nonatomic, strong) UIFont *naviTitleFont;
240   -@property (nonatomic, strong) UIColor *barItemTextColor;
241   -@property (nonatomic, strong) UIFont *barItemTextFont;
242   -@property (nonatomic, strong) UIColor *editBtnTitleColor;///LXG编辑按钮title颜色
243   -
244   -@property (nonatomic, copy) NSString *doneBtnTitleStr;
245   -@property (nonatomic, copy) NSString *cancelBtnTitleStr;
246   -@property (nonatomic, copy) NSString *previewBtnTitleStr;
247   -@property (nonatomic, copy) NSString *fullImageBtnTitleStr;
248   -@property (nonatomic, copy) NSString *settingBtnTitleStr;
249   -@property (nonatomic, copy) NSString *processHintStr;
250   -@property (nonatomic, copy) NSString *editBtnTitleStr;///LXG编辑按钮
251   -
252   -
253   -
254   -/// Icon theme color, default is green color like wechat, the value is r:31 g:185 b:34. Currently only support image selection icon when showSelectedIndex is YES. If you need it, please set it as soon as possible
255   -/// icon主题色,默认是微信的绿色,值是r:31 g:185 b:34。目前仅支持showSelectedIndex为YES时的图片选中icon。如需要,请尽早设置它。
256   -@property (strong, nonatomic) UIColor *iconThemeColor;
257   -
258   -#pragma mark -
259   -- (void)cancelButtonClick;
260   -
261   -// The picker should dismiss itself; when it dismissed these handle will be called.
262   -// You can also set autoDismiss to NO, then the picker don't dismiss itself.
263   -// If isOriginalPhoto is YES, user picked the original photo.
264   -// You can get original photo with asset, by the method [[TZImageManager manager] getOriginalPhotoWithAsset:completion:].
265   -// The UIImage Object in photos default width is 828px, you can set it by photoWidth property.
266   -// 这个照片选择器会自己dismiss,当选择器dismiss的时候,会执行下面的handle
267   -// 你也可以设置autoDismiss属性为NO,选择器就不会自己dismis了
268   -// 如果isSelectOriginalPhoto为YES,表明用户选择了原图
269   -// 你可以通过一个asset获得原图,通过这个方法:[[TZImageManager manager] getOriginalPhotoWithAsset:completion:]
270   -// photos数组里的UIImage对象,默认是828像素宽,你可以通过设置photoWidth属性的值来改变它
271   -@property (nonatomic, copy) void (^didFinishPickingPhotosHandle)(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto);
272   -@property (nonatomic, copy) void (^didFinishPickingPhotosWithInfosHandle)(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto,NSArray<NSDictionary *> *infos);
273   -@property (nonatomic, copy) void (^imagePickerControllerDidCancelHandle)(void);
274   -
275   -// If user picking a video, this handle will be called.
276   -// If system version > iOS8,asset is kind of PHAsset class, else is ALAsset class.
277   -// 如果用户选择了一个视频,下面的handle会被执行
278   -// 如果系统版本大于iOS8,asset是PHAsset类的对象,否则是ALAsset类的对象
279   -@property (nonatomic, copy) void (^didFinishPickingVideoHandle)(UIImage *coverImage,id asset);
280   -
281   -// If user picking a gif image, this callback will be called.
282   -// 如果用户选择了一个gif图片,下面的handle会被执行
283   -@property (nonatomic, copy) void (^didFinishPickingGifImageHandle)(UIImage *animatedImage,id sourceAssets);
284   -
285   -@property (nonatomic, weak) id<TZImagePickerControllerDelegate> pickerDelegate;
286   -
287   -@end
288   -
289   -
290   -@protocol TZImagePickerControllerDelegate <NSObject>
291   -@optional
292   -// The picker should dismiss itself; when it dismissed these handle will be called.
293   -// You can also set autoDismiss to NO, then the picker don't dismiss itself.
294   -// If isOriginalPhoto is YES, user picked the original photo.
295   -// You can get original photo with asset, by the method [[TZImageManager manager] getOriginalPhotoWithAsset:completion:].
296   -// The UIImage Object in photos default width is 828px, you can set it by photoWidth property.
297   -// 这个照片选择器会自己dismiss,当选择器dismiss的时候,会执行下面的handle
298   -// 你也可以设置autoDismiss属性为NO,选择器就不会自己dismis了
299   -// 如果isSelectOriginalPhoto为YES,表明用户选择了原图
300   -// 你可以通过一个asset获得原图,通过这个方法:[[TZImageManager manager] getOriginalPhotoWithAsset:completion:]
301   -// photos数组里的UIImage对象,默认是828像素宽,你可以通过设置photoWidth属性的值来改变它
302   -- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto;
303   -- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto infos:(NSArray<NSDictionary *> *)infos;
304   -//- (void)imagePickerControllerDidCancel:(TZImagePickerController *)picker __attribute__((deprecated("Use -tz_imagePickerControllerDidCancel:.")));
305   -- (void)tz_imagePickerControllerDidCancel:(TZImagePickerController *)picker;
306   -
307   -// If user picking a video, this callback will be called.
308   -// If system version > iOS8,asset is kind of PHAsset class, else is ALAsset class.
309   -// 如果用户选择了一个视频,下面的handle会被执行
310   -// 如果系统版本大于iOS8,asset是PHAsset类的对象,否则是ALAsset类的对象
311   -- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingVideo:(UIImage *)coverImage sourceAssets:(id)asset;
312   -
313   -// If user picking a gif image, this callback will be called.
314   -// 如果用户选择了一个gif图片,下面的handle会被执行
315   -- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingGifImage:(UIImage *)animatedImage sourceAssets:(id)asset;
316   -
317   -// Decide album show or not't
318   -// 决定相册显示与否 albumName:相册名字 result:相册原始数据
319   -- (BOOL)isAlbumCanSelect:(NSString *)albumName result:(id)result;
320   -
321   -// Decide asset show or not't
322   -// 决定照片显示与否
323   -- (BOOL)isAssetCanSelect:(id)asset;
324   -@end
325   -
326   -
327   -@interface TZAlbumPickerController : UIViewController
328   -@property (nonatomic, assign) NSInteger columnNumber;
329   -@property (assign, nonatomic) BOOL isFirstAppear;
330   -- (void)configTableView;
331   -@end
332   -
333   -
334   -@interface UIImage (MyBundle)
335   -+ (UIImage *)imageNamedFromMyBundle:(NSString *)name;
336   -@end
337   -
338   -
339   -@interface NSString (TzExtension)
340   -- (BOOL)tz_containsString:(NSString *)string;
341   -- (CGSize)tz_calculateSizeWithAttributes:(NSDictionary *)attributes maxSize:(CGSize)maxSize;
342   -@end
343   -
344   -
345   -@interface TZCommonTools : NSObject
346   -+ (BOOL)tz_isIPhoneX;
347   -+ (CGFloat)tz_statusBarHeight;
348   -// 获得Info.plist数据字典
349   -+ (NSDictionary *)tz_getInfoDictionary;
350   -@end
351   -
352   -
353   -@interface TZImagePickerConfig : NSObject
354   -+ (instancetype)sharedInstance;
355   -@property (copy, nonatomic) NSString *preferredLanguage;
356   -@property(nonatomic, assign) BOOL allowPickingImage;
357   -@property (nonatomic, assign) BOOL allowPickingVideo;
358   -@property (strong, nonatomic) NSBundle *languageBundle;
359   -/// 默认是200,如果一个GIF过大,里面图片个数可能超过1000,会导致内存飙升而崩溃
360   -@property (assign, nonatomic) NSInteger gifPreviewMaxImagesCount;
361   -@property (assign, nonatomic) BOOL showSelectedIndex;
362   -@property (assign, nonatomic) BOOL showPhotoCannotSelectLayer;
363   -@property (assign, nonatomic) BOOL notScaleImage;
364   -@property (assign, nonatomic) BOOL needFixComposition;
365   -@end
CNLiveImagePickerController/TZImagePickerController.m deleted 100755 → 0
1   -//
2   -// TZImagePickerController.m
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 15/12/24.
6   -// Copyright © 2015年 谭真. All rights reserved.
7   -// version 2.2.6 - 2018.08.21
8   -// 更多信息,请前往项目的github地址:https://github.com/banchichen/TZImagePickerController
9   -
10   -#import "TZImagePickerController.h"
11   -#import "TZPhotoPickerController.h"
12   -#import "TZPhotoPreviewController.h"
13   -#import "TZAssetModel.h"
14   -#import "TZAssetCell.h"
15   -#import "UIView+Layout.h"
16   -#import "TZImageManager.h"
17   -#import <sys/utsname.h>
18   -
19   -@interface TZImagePickerController () {
20   - NSTimer *_timer;
21   - UILabel *_tipLabel;
22   - UIButton *_settingBtn;
23   - BOOL _pushPhotoPickerVc;
24   - BOOL _didPushPhotoPickerVc;
25   -
26   - UIButton *_progressHUD;
27   - UIView *_HUDContainer;
28   - UIActivityIndicatorView *_HUDIndicatorView;
29   - UILabel *_HUDLabel;
30   -
31   - UIStatusBarStyle _originStatusBarStyle;
32   -}
33   -/// Default is 4, Use in photos collectionView in TZPhotoPickerController
34   -/// 默认4列, TZPhotoPickerController中的照片collectionView
35   -@property (nonatomic, assign) NSInteger columnNumber;
36   -@end
37   -
38   -@implementation TZImagePickerController
39   -
40   -- (instancetype)init {
41   - self = [super init];
42   - if (self) {
43   - self = [self initWithMaxImagesCount:9 delegate:nil];
44   - }
45   - return self;
46   -}
47   -
48   -#pragma clang diagnostic push
49   -#pragma clang diagnostic ignored "-Wdeprecated-declarations"
50   -- (void)viewDidLoad {
51   - [super viewDidLoad];
52   - self.needShowStatusBar = ![UIApplication sharedApplication].statusBarHidden;
53   - self.view.backgroundColor = [UIColor whiteColor];
54   - self.navigationBar.barStyle = UIBarStyleBlack;
55   - self.navigationBar.translucent = YES;
56   - [TZImageManager manager].shouldFixOrientation = NO;
57   -
58   - // Default appearance, you can reset these after this method
59   - // 默认的外观,你可以在这个方法后重置
60   - self.oKButtonTitleColorNormal = [UIColor colorWithRed:(83/255.0) green:(179/255.0) blue:(17/255.0) alpha:1.0];
61   - self.oKButtonTitleColorDisabled = [UIColor colorWithRed:(83/255.0) green:(179/255.0) blue:(17/255.0) alpha:0.5];
62   - self.editBtnTitleColor = [UIColor colorWithRed:(83/255.0) green:(179/255.0) blue:(17/255.0) alpha:1.0];///LXG 默认编辑按钮颜色
63   -
64   - if (iOS7Later) {
65   - self.navigationBar.barTintColor = [UIColor colorWithRed:(34/255.0) green:(34/255.0) blue:(34/255.0) alpha:1.0];
66   - self.navigationBar.tintColor = [UIColor whiteColor];
67   - self.automaticallyAdjustsScrollViewInsets = NO;
68   - if (self.needShowStatusBar) [UIApplication sharedApplication].statusBarHidden = NO;
69   - }
70   -}
71   -
72   -- (void)setNaviBgColor:(UIColor *)naviBgColor {
73   - _naviBgColor = naviBgColor;
74   - if (iOS7Later) {
75   - self.navigationBar.barTintColor = naviBgColor;
76   - }
77   -}
78   -
79   -- (void)setNaviTitleColor:(UIColor *)naviTitleColor {
80   - _naviTitleColor = naviTitleColor;
81   - [self configNaviTitleAppearance];
82   -}
83   -
84   -- (void)setNaviTitleFont:(UIFont *)naviTitleFont {
85   - _naviTitleFont = naviTitleFont;
86   - [self configNaviTitleAppearance];
87   -}
88   -
89   -- (void)configNaviTitleAppearance {
90   - NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
91   - if (self.naviTitleColor) {
92   - textAttrs[NSForegroundColorAttributeName] = self.naviTitleColor;
93   - }
94   - if (self.naviTitleFont) {
95   - textAttrs[NSFontAttributeName] = self.naviTitleFont;
96   - }
97   - self.navigationBar.titleTextAttributes = textAttrs;
98   -}
99   -
100   -- (void)setBarItemTextFont:(UIFont *)barItemTextFont {
101   - _barItemTextFont = barItemTextFont;
102   - [self configBarButtonItemAppearance];
103   -}
104   -
105   -- (void)setBarItemTextColor:(UIColor *)barItemTextColor {
106   - _barItemTextColor = barItemTextColor;
107   - [self configBarButtonItemAppearance];
108   -}
109   -
110   -- (void)setIsStatusBarDefault:(BOOL)isStatusBarDefault {
111   - _isStatusBarDefault = isStatusBarDefault;
112   -
113   - if (isStatusBarDefault) {
114   - self.statusBarStyle = iOS7Later ? UIStatusBarStyleDefault : UIStatusBarStyleBlackOpaque;
115   - } else {
116   - self.statusBarStyle = iOS7Later ? UIStatusBarStyleLightContent : UIStatusBarStyleBlackOpaque;
117   - }
118   -}
119   -
120   -- (void)configBarButtonItemAppearance {
121   - UIBarButtonItem *barItem;
122   - if (@available(iOS 9, *)) {
123   - barItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[TZImagePickerController class]]];
124   - } else {
125   - barItem = [UIBarButtonItem appearanceWhenContainedIn:[TZImagePickerController class], nil];
126   - }
127   - NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
128   - textAttrs[NSForegroundColorAttributeName] = self.barItemTextColor;
129   - textAttrs[NSFontAttributeName] = self.barItemTextFont;
130   - [barItem setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
131   -}
132   -
133   -- (void)viewWillAppear:(BOOL)animated {
134   - [super viewWillAppear:animated];
135   - _originStatusBarStyle = [UIApplication sharedApplication].statusBarStyle;
136   - [UIApplication sharedApplication].statusBarStyle = self.statusBarStyle;
137   -}
138   -
139   -- (void)viewWillDisappear:(BOOL)animated {
140   - [super viewWillDisappear:animated];
141   - [UIApplication sharedApplication].statusBarStyle = _originStatusBarStyle;
142   - [self hideProgressHUD];
143   -}
144   -
145   -- (UIStatusBarStyle)preferredStatusBarStyle {
146   - return self.statusBarStyle;
147   -}
148   -
149   -- (instancetype)initWithMaxImagesCount:(NSInteger)maxImagesCount delegate:(id<TZImagePickerControllerDelegate>)delegate {
150   - return [self initWithMaxImagesCount:maxImagesCount columnNumber:4 delegate:delegate pushPhotoPickerVc:YES];
151   -}
152   -
153   -- (instancetype)initWithMaxImagesCount:(NSInteger)maxImagesCount columnNumber:(NSInteger)columnNumber delegate:(id<TZImagePickerControllerDelegate>)delegate {
154   - return [self initWithMaxImagesCount:maxImagesCount columnNumber:columnNumber delegate:delegate pushPhotoPickerVc:YES];
155   -}
156   -
157   -- (instancetype)initWithMaxImagesCount:(NSInteger)maxImagesCount columnNumber:(NSInteger)columnNumber delegate:(id<TZImagePickerControllerDelegate>)delegate pushPhotoPickerVc:(BOOL)pushPhotoPickerVc {
158   - _pushPhotoPickerVc = pushPhotoPickerVc;
159   - TZAlbumPickerController *albumPickerVc = [[TZAlbumPickerController alloc] init];
160   - albumPickerVc.isFirstAppear = YES;
161   - albumPickerVc.columnNumber = columnNumber;
162   - self = [super initWithRootViewController:albumPickerVc];
163   - if (self) {
164   - self.maxImagesCount = maxImagesCount > 0 ? maxImagesCount : 9; // Default is 9 / 默认最大可选9张图片
165   - self.pickerDelegate = delegate;
166   - self.selectedAssets = [NSMutableArray array];
167   -
168   -#pragma mark - ADD:视频编辑(LXG)
169   - self.maxEditVideoTime = 10;
170   - self.maxVideoDuration = 120;
171   - // Allow user picking original photo and video, you also can set No after this method
172   - // 默认准许用户选择原图和视频, 你也可以在这个方法后置为NO
173   - self.allowPickingOriginalPhoto = YES;
174   - self.allowPickingVideo = YES;
175   - self.allowPickingImage = YES;
176   - self.allowTakePicture = YES;
177   - self.allowTakeVideo = YES;
178   - self.videoMaximumDuration = 10 * 60;
179   - self.sortAscendingByModificationDate = YES;
180   - self.autoDismiss = YES;
181   - self.columnNumber = columnNumber;
182   - [self configDefaultSetting];
183   -
184   - if (![[TZImageManager manager] authorizationStatusAuthorized]) {
185   - _tipLabel = [[UILabel alloc] init];
186   - _tipLabel.frame = CGRectMake(8, 120, self.view.tz_width - 16, 60);
187   - _tipLabel.textAlignment = NSTextAlignmentCenter;
188   - _tipLabel.numberOfLines = 0;
189   - _tipLabel.font = [UIFont systemFontOfSize:16];
190   - _tipLabel.textColor = [UIColor blackColor];
191   -
192   - NSDictionary *infoDict = [TZCommonTools tz_getInfoDictionary];
193   - NSString *appName = [infoDict valueForKey:@"CFBundleDisplayName"];
194   - if (!appName) appName = [infoDict valueForKey:@"CFBundleName"];
195   - NSString *tipText = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Allow %@ to access your album in \"Settings -> Privacy -> Photos\""],appName];
196   - _tipLabel.text = tipText;
197   - [self.view addSubview:_tipLabel];
198   -
199   - if (iOS8Later) {
200   - _settingBtn = [UIButton buttonWithType:UIButtonTypeSystem];
201   - [_settingBtn setTitle:self.settingBtnTitleStr forState:UIControlStateNormal];
202   - _settingBtn.frame = CGRectMake(0, 180, self.view.tz_width, 44);
203   - _settingBtn.titleLabel.font = [UIFont systemFontOfSize:18];
204   - [_settingBtn addTarget:self action:@selector(settingBtnClick) forControlEvents:UIControlEventTouchUpInside];
205   - [self.view addSubview:_settingBtn];
206   - }
207   -
208   - if ([TZImageManager authorizationStatus] == 0) {
209   - _timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(observeAuthrizationStatusChange) userInfo:nil repeats:NO];
210   - }
211   - } else {
212   - [self pushPhotoPickerVc];
213   - }
214   - }
215   - return self;
216   -}
217   -
218   -/// This init method just for previewing photos / 用这个初始化方法以预览图片
219   -- (instancetype)initWithSelectedAssets:(NSMutableArray *)selectedAssets selectedPhotos:(NSMutableArray *)selectedPhotos index:(NSInteger)index{
220   - TZPhotoPreviewController *previewVc = [[TZPhotoPreviewController alloc] init];
221   - self = [super initWithRootViewController:previewVc];
222   - if (self) {
223   - self.selectedAssets = [NSMutableArray arrayWithArray:selectedAssets];
224   - self.allowPickingOriginalPhoto = self.allowPickingOriginalPhoto;
225   - [self configDefaultSetting];
226   -
227   - previewVc.photos = [NSMutableArray arrayWithArray:selectedPhotos];
228   - previewVc.currentIndex = index;
229   - __weak typeof(self) weakSelf = self;
230   - [previewVc setDoneButtonClickBlockWithPreviewType:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
231   - __strong typeof(weakSelf) strongSelf = weakSelf;
232   - [strongSelf dismissViewControllerAnimated:YES completion:^{
233   - if (!strongSelf) return;
234   - if (strongSelf.didFinishPickingPhotosHandle) {
235   - strongSelf.didFinishPickingPhotosHandle(photos,assets,isSelectOriginalPhoto);
236   - }
237   - }];
238   - }];
239   - }
240   - return self;
241   -}
242   -
243   -/// This init method for crop photo / 用这个初始化方法以裁剪图片
244   -- (instancetype)initCropTypeWithAsset:(id)asset photo:(UIImage *)photo completion:(void (^)(UIImage *cropImage,id asset))completion {
245   - TZPhotoPreviewController *previewVc = [[TZPhotoPreviewController alloc] init];
246   - self = [super initWithRootViewController:previewVc];
247   - if (self) {
248   - self.maxImagesCount = 1;
249   - self.allowCrop = YES;
250   - self.selectedAssets = [NSMutableArray arrayWithArray:@[asset]];
251   - [self configDefaultSetting];
252   -
253   - previewVc.photos = [NSMutableArray arrayWithArray:@[photo]];
254   - previewVc.isCropImage = YES;
255   - previewVc.currentIndex = 0;
256   - __weak typeof(self) weakSelf = self;
257   - [previewVc setDoneButtonClickBlockCropMode:^(UIImage *cropImage, id asset) {
258   - __strong typeof(weakSelf) strongSelf = weakSelf;
259   - [strongSelf dismissViewControllerAnimated:YES completion:^{
260   - if (completion) {
261   - completion(cropImage,asset);
262   - }
263   - }];
264   - }];
265   - }
266   - return self;
267   -}
268   -
269   -- (void)configDefaultSetting {
270   - self.timeout = 15;
271   - self.photoWidth = 828.0;
272   - self.photoPreviewMaxWidth = 600;
273   - self.naviTitleColor = [UIColor whiteColor];
274   - self.naviTitleFont = [UIFont systemFontOfSize:17];
275   - self.barItemTextFont = [UIFont systemFontOfSize:15];
276   - self.barItemTextColor = [UIColor whiteColor];
277   - self.allowPreview = YES;
278   - // 2.2.26版本,不主动缩放图片,降低内存占用
279   - self.notScaleImage = YES;
280   - self.needFixComposition = NO;
281   - self.statusBarStyle = UIStatusBarStyleLightContent;
282   - self.cannotSelectLayerColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8];
283   - self.allowCameraLocation = YES;
284   -
285   - self.iconThemeColor = [UIColor colorWithRed:31 / 255.0 green:185 / 255.0 blue:34 / 255.0 alpha:1.0];
286   - [self configDefaultBtnTitle];
287   -
288   - CGFloat cropViewWH = MIN(self.view.tz_width, self.view.tz_height) / 3 * 2;
289   - self.cropRect = CGRectMake((self.view.tz_width - cropViewWH) / 2, (self.view.tz_height - cropViewWH) / 2, cropViewWH, cropViewWH);
290   -}
291   -
292   -- (void)configDefaultImageName {
293   - self.takePictureImageName = @"takePicture80";
294   - self.photoSelImageName = @"photo_sel_photoPickerVc";
295   - self.photoDefImageName = @"photo_def_photoPickerVc";
296   - self.photoNumberIconImage = [self createImageWithColor:nil size:CGSizeMake(24, 24) radius:12]; // @"photo_number_icon";
297   - self.photoPreviewOriginDefImageName = @"preview_original_def";
298   - self.photoOriginDefImageName = @"photo_original_def";
299   - self.photoOriginSelImageName = @"photo_original_sel";
300   -}
301   -
302   -- (void)setTakePictureImageName:(NSString *)takePictureImageName {
303   - _takePictureImageName = takePictureImageName;
304   - _takePictureImage = [UIImage imageNamedFromMyBundle:takePictureImageName];
305   -}
306   -
307   -- (void)setPhotoSelImageName:(NSString *)photoSelImageName {
308   - _photoSelImageName = photoSelImageName;
309   - _photoSelImage = [UIImage imageNamedFromMyBundle:photoSelImageName];
310   -}
311   -
312   -- (void)setPhotoDefImageName:(NSString *)photoDefImageName {
313   - _photoDefImageName = photoDefImageName;
314   - _photoDefImage = [UIImage imageNamedFromMyBundle:photoDefImageName];
315   -}
316   -
317   -- (void)setPhotoNumberIconImageName:(NSString *)photoNumberIconImageName {
318   - _photoNumberIconImageName = photoNumberIconImageName;
319   - _photoNumberIconImage = [UIImage imageNamedFromMyBundle:photoNumberIconImageName];
320   -}
321   -
322   -- (void)setPhotoPreviewOriginDefImageName:(NSString *)photoPreviewOriginDefImageName {
323   - _photoPreviewOriginDefImageName = photoPreviewOriginDefImageName;
324   - _photoPreviewOriginDefImage = [UIImage imageNamedFromMyBundle:photoPreviewOriginDefImageName];
325   -}
326   -
327   -- (void)setPhotoOriginDefImageName:(NSString *)photoOriginDefImageName {
328   - _photoOriginDefImageName = photoOriginDefImageName;
329   - _photoOriginDefImage = [UIImage imageNamedFromMyBundle:photoOriginDefImageName];
330   -}
331   -
332   -- (void)setPhotoOriginSelImageName:(NSString *)photoOriginSelImageName {
333   - _photoOriginSelImageName = photoOriginSelImageName;
334   - _photoOriginSelImage = [UIImage imageNamedFromMyBundle:photoOriginSelImageName];
335   -}
336   -
337   -- (void)setIconThemeColor:(UIColor *)iconThemeColor {
338   - _iconThemeColor = iconThemeColor;
339   - [self configDefaultImageName];
340   -}
341   -
342   -- (void)configDefaultBtnTitle {
343   - self.doneBtnTitleStr = [NSBundle tz_localizedStringForKey:@"Done"];
344   - self.cancelBtnTitleStr = [NSBundle tz_localizedStringForKey:@"Cancel"];
345   - self.previewBtnTitleStr = [NSBundle tz_localizedStringForKey:@"Preview"];
346   - self.fullImageBtnTitleStr = [NSBundle tz_localizedStringForKey:@"Full image"];
347   - self.settingBtnTitleStr = [NSBundle tz_localizedStringForKey:@"Setting"];
348   - self.processHintStr = [NSBundle tz_localizedStringForKey:@"Processing..."];
349   - self.editBtnTitleStr = [NSBundle tz_localizedStringForKey:@"Edit"];
350   -}
351   -
352   -- (void)setShowSelectedIndex:(BOOL)showSelectedIndex {
353   - _showSelectedIndex = showSelectedIndex;
354   - if (showSelectedIndex) {
355   - self.photoSelImage = [self createImageWithColor:nil size:CGSizeMake(24, 24) radius:12];
356   - }
357   - [TZImagePickerConfig sharedInstance].showSelectedIndex = showSelectedIndex;
358   -}
359   -
360   -- (void)setShowPhotoCannotSelectLayer:(BOOL)showPhotoCannotSelectLayer {
361   - _showPhotoCannotSelectLayer = showPhotoCannotSelectLayer;
362   - [TZImagePickerConfig sharedInstance].showPhotoCannotSelectLayer = showPhotoCannotSelectLayer;
363   -}
364   -
365   -- (void)setNotScaleImage:(BOOL)notScaleImage {
366   - _notScaleImage = notScaleImage;
367   - [TZImagePickerConfig sharedInstance].notScaleImage = notScaleImage;
368   -}
369   -
370   -- (void)setNeedFixComposition:(BOOL)needFixComposition {
371   - _needFixComposition = needFixComposition;
372   - [TZImagePickerConfig sharedInstance].needFixComposition = needFixComposition;
373   -}
374   -
375   -- (void)observeAuthrizationStatusChange {
376   - [_timer invalidate];
377   - _timer = nil;
378   - if ([TZImageManager authorizationStatus] == 0) {
379   - _timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(observeAuthrizationStatusChange) userInfo:nil repeats:NO];
380   - }
381   -
382   - if ([[TZImageManager manager] authorizationStatusAuthorized]) {
383   - [_tipLabel removeFromSuperview];
384   - [_settingBtn removeFromSuperview];
385   -
386   - [self pushPhotoPickerVc];
387   -
388   - TZAlbumPickerController *albumPickerVc = (TZAlbumPickerController *)self.visibleViewController;
389   - if ([albumPickerVc isKindOfClass:[TZAlbumPickerController class]]) {
390   - [albumPickerVc configTableView];
391   - }
392   - }
393   -}
394   -
395   -- (void)pushPhotoPickerVc {
396   - _didPushPhotoPickerVc = NO;
397   - // 1.6.8 判断是否需要push到照片选择页,如果_pushPhotoPickerVc为NO,则不push
398   - if (!_didPushPhotoPickerVc && _pushPhotoPickerVc) {
399   - TZPhotoPickerController *photoPickerVc = [[TZPhotoPickerController alloc] init];
400   - photoPickerVc.isFirstAppear = YES;
401   - photoPickerVc.columnNumber = self.columnNumber;
402   - [[TZImageManager manager] getCameraRollAlbum:self.allowPickingVideo allowPickingImage:self.allowPickingImage needFetchAssets:NO completion:^(TZAlbumModel *model) {
403   - photoPickerVc.model = model;
404   - [self pushViewController:photoPickerVc animated:YES];
405   - self->_didPushPhotoPickerVc = YES;
406   - }];
407   - }
408   -}
409   -
410   -- (id)showAlertWithTitle:(NSString *)title {
411   - if (iOS8Later) {
412   - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleAlert];
413   - [alertController addAction:[UIAlertAction actionWithTitle:[NSBundle tz_localizedStringForKey:@"OK"] style:UIAlertActionStyleDefault handler:nil]];
414   - [self presentViewController:alertController animated:YES completion:nil];
415   - return alertController;
416   - } else {
417   - UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:nil delegate:nil cancelButtonTitle:[NSBundle tz_localizedStringForKey:@"OK"] otherButtonTitles:nil, nil];
418   - [alertView show];
419   - return alertView;
420   - }
421   -}
422   -
423   -- (void)hideAlertView:(id)alertView {
424   - if ([alertView isKindOfClass:[UIAlertController class]]) {
425   - UIAlertController *alertC = alertView;
426   - [alertC dismissViewControllerAnimated:YES completion:nil];
427   - } else if ([alertView isKindOfClass:[UIAlertView class]]) {
428   - UIAlertView *alertV = alertView;
429   - [alertV dismissWithClickedButtonIndex:0 animated:YES];
430   - }
431   - alertView = nil;
432   -}
433   -
434   -- (void)showProgressHUD {
435   - if (!_progressHUD) {
436   - _progressHUD = [UIButton buttonWithType:UIButtonTypeCustom];
437   - [_progressHUD setBackgroundColor:[UIColor clearColor]];
438   - _progressHUD.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);///解决多次点击内存溢出问题(lxg)
439   -
440   - _HUDContainer = [[UIView alloc] init];
441   - _HUDContainer.layer.cornerRadius = 8;
442   - _HUDContainer.clipsToBounds = YES;
443   - _HUDContainer.backgroundColor = [UIColor darkGrayColor];
444   - _HUDContainer.alpha = 0.7;
445   -
446   - _HUDIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
447   -
448   - _HUDLabel = [[UILabel alloc] init];
449   - _HUDLabel.textAlignment = NSTextAlignmentCenter;
450   - _HUDLabel.text = self.processHintStr;
451   - _HUDLabel.font = [UIFont systemFontOfSize:15];
452   - _HUDLabel.textColor = [UIColor whiteColor];
453   -
454   - [_HUDContainer addSubview:_HUDLabel];
455   - [_HUDContainer addSubview:_HUDIndicatorView];
456   - [_progressHUD addSubview:_HUDContainer];
457   - }
458   - [_HUDIndicatorView startAnimating];
459   - [[UIApplication sharedApplication].keyWindow addSubview:_progressHUD];
460   -
461   - // if over time, dismiss HUD automatic
462   - __weak typeof(self) weakSelf = self;
463   - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.timeout * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
464   - __strong typeof(weakSelf) strongSelf = weakSelf;
465   - [strongSelf hideProgressHUD];
466   - });
467   -}
468   -
469   -- (void)hideProgressHUD {
470   - if (_progressHUD) {
471   - [_HUDIndicatorView stopAnimating];
472   - [_progressHUD removeFromSuperview];
473   - }
474   -}
475   -
476   -- (void)setMaxImagesCount:(NSInteger)maxImagesCount {
477   - _maxImagesCount = maxImagesCount;
478   - if (maxImagesCount > 1) {
479   - _showSelectBtn = YES;
480   - _allowCrop = NO;
481   - }
482   -}
483   -
484   -- (void)setShowSelectBtn:(BOOL)showSelectBtn {
485   - _showSelectBtn = showSelectBtn;
486   - // 多选模式下,不允许让showSelectBtn为NO
487   - if (!showSelectBtn && _maxImagesCount > 1) {
488   - _showSelectBtn = YES;
489   - }
490   -}
491   -
492   -- (void)setAllowCrop:(BOOL)allowCrop {
493   - _allowCrop = _maxImagesCount > 1 ? NO : allowCrop;
494   - if (allowCrop) { // 允许裁剪的时候,不能选原图和GIF
495   - self.allowPickingOriginalPhoto = NO;
496   - self.allowPickingGif = NO;
497   - }
498   -}
499   -
500   -- (void)setCircleCropRadius:(NSInteger)circleCropRadius {
501   - _circleCropRadius = circleCropRadius;
502   - self.cropRect = CGRectMake(self.view.tz_width / 2 - circleCropRadius, self.view.tz_height / 2 - _circleCropRadius, _circleCropRadius * 2, _circleCropRadius * 2);
503   -}
504   -
505   -- (void)setCropRect:(CGRect)cropRect {
506   - _cropRect = cropRect;
507   - _cropRectPortrait = cropRect;
508   - CGFloat widthHeight = cropRect.size.width;
509   - _cropRectLandscape = CGRectMake((self.view.tz_height - widthHeight) / 2, cropRect.origin.x, widthHeight, widthHeight);
510   -}
511   -
512   -- (void)setTimeout:(NSInteger)timeout {
513   - _timeout = timeout;
514   - if (timeout < 5) {
515   - _timeout = 5;
516   - } else if (_timeout > 60) {
517   - _timeout = 60;
518   - }
519   -}
520   -
521   -- (void)setPickerDelegate:(id<TZImagePickerControllerDelegate>)pickerDelegate {
522   - _pickerDelegate = pickerDelegate;
523   - [TZImageManager manager].pickerDelegate = pickerDelegate;
524   -}
525   -
526   -- (void)setColumnNumber:(NSInteger)columnNumber {
527   - _columnNumber = columnNumber;
528   - if (columnNumber <= 2) {
529   - _columnNumber = 2;
530   - } else if (columnNumber >= 6) {
531   - _columnNumber = 6;
532   - }
533   -
534   - TZAlbumPickerController *albumPickerVc = [self.childViewControllers firstObject];
535   - albumPickerVc.columnNumber = _columnNumber;
536   - [TZImageManager manager].columnNumber = _columnNumber;
537   -}
538   -
539   -- (void)setMinPhotoWidthSelectable:(NSInteger)minPhotoWidthSelectable {
540   - _minPhotoWidthSelectable = minPhotoWidthSelectable;
541   - [TZImageManager manager].minPhotoWidthSelectable = minPhotoWidthSelectable;
542   -}
543   -
544   -- (void)setMinPhotoHeightSelectable:(NSInteger)minPhotoHeightSelectable {
545   - _minPhotoHeightSelectable = minPhotoHeightSelectable;
546   - [TZImageManager manager].minPhotoHeightSelectable = minPhotoHeightSelectable;
547   -}
548   -
549   -- (void)setHideWhenCanNotSelect:(BOOL)hideWhenCanNotSelect {
550   - _hideWhenCanNotSelect = hideWhenCanNotSelect;
551   - [TZImageManager manager].hideWhenCanNotSelect = hideWhenCanNotSelect;
552   -}
553   -
554   -- (void)setPhotoPreviewMaxWidth:(CGFloat)photoPreviewMaxWidth {
555   - _photoPreviewMaxWidth = photoPreviewMaxWidth;
556   - if (photoPreviewMaxWidth > 800) {
557   - _photoPreviewMaxWidth = 800;
558   - } else if (photoPreviewMaxWidth < 500) {
559   - _photoPreviewMaxWidth = 500;
560   - }
561   - [TZImageManager manager].photoPreviewMaxWidth = _photoPreviewMaxWidth;
562   -}
563   -
564   -- (void)setPhotoWidth:(CGFloat)photoWidth {
565   - _photoWidth = photoWidth;
566   - [TZImageManager manager].photoWidth = photoWidth;
567   -}
568   -
569   -- (void)setSelectedAssets:(NSMutableArray *)selectedAssets {
570   - _selectedAssets = selectedAssets;
571   - _selectedModels = [NSMutableArray array];
572   - _selectedAssetIds = [NSMutableArray array];
573   - for (id asset in selectedAssets) {
574   - TZAssetModel *model = [TZAssetModel modelWithAsset:asset type:[[TZImageManager manager] getAssetType:asset]];
575   - model.isSelected = YES;
576   - [self addSelectedModel:model];
577   - }
578   -}
579   -
580   -- (void)setAllowPickingImage:(BOOL)allowPickingImage {
581   - _allowPickingImage = allowPickingImage;
582   - [TZImagePickerConfig sharedInstance].allowPickingImage = allowPickingImage;
583   - if (!allowPickingImage) {
584   - _allowTakePicture = NO;
585   - }
586   -}
587   -
588   -- (void)setAllowPickingVideo:(BOOL)allowPickingVideo {
589   - _allowPickingVideo = allowPickingVideo;
590   - [TZImagePickerConfig sharedInstance].allowPickingVideo = allowPickingVideo;
591   - if (!allowPickingVideo) {
592   - _allowTakeVideo = NO;
593   - }
594   -}
595   -
596   -- (void)setPreferredLanguage:(NSString *)preferredLanguage {
597   - _preferredLanguage = preferredLanguage;
598   - [TZImagePickerConfig sharedInstance].preferredLanguage = preferredLanguage;
599   - [self configDefaultBtnTitle];
600   -}
601   -
602   -- (void)setLanguageBundle:(NSBundle *)languageBundle {
603   - _languageBundle = languageBundle;
604   - [TZImagePickerConfig sharedInstance].languageBundle = languageBundle;
605   - [self configDefaultBtnTitle];
606   -}
607   -
608   -- (void)setSortAscendingByModificationDate:(BOOL)sortAscendingByModificationDate {
609   - _sortAscendingByModificationDate = sortAscendingByModificationDate;
610   - [TZImageManager manager].sortAscendingByModificationDate = sortAscendingByModificationDate;
611   -}
612   -
613   -- (void)settingBtnClick {
614   - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
615   -}
616   -
617   -- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
618   - if (iOS7Later) {
619   - viewController.automaticallyAdjustsScrollViewInsets = NO;
620   - }
621   - [super pushViewController:viewController animated:animated];
622   -}
623   -
624   -- (void)dealloc {
625   - // NSLog(@"%@ dealloc",NSStringFromClass(self.class));
626   -}
627   -
628   -- (void)addSelectedModel:(TZAssetModel *)model {
629   - [_selectedModels addObject:model];
630   - NSString *assetId = [[TZImageManager manager] getAssetIdentifier:model.asset];
631   - [_selectedAssetIds addObject:assetId];
632   -}
633   -
634   -- (void)removeSelectedModel:(TZAssetModel *)model {
635   - [_selectedModels removeObject:model];
636   - NSString *assetId = [[TZImageManager manager] getAssetIdentifier:model.asset];
637   - [_selectedAssetIds removeObject:assetId];
638   -}
639   -
640   -- (UIImage *)createImageWithColor:(UIColor *)color size:(CGSize)size radius:(CGFloat)radius {
641   - if (!color) {
642   - color = self.iconThemeColor;
643   - }
644   - CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
645   - UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
646   - CGContextRef context = UIGraphicsGetCurrentContext();
647   - CGContextSetFillColorWithColor(context, [color CGColor]);
648   - UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
649   - CGContextAddPath(context, path.CGPath);
650   - CGContextFillPath(context);
651   - UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
652   - UIGraphicsEndImageContext();
653   - return image;
654   -}
655   -
656   -#pragma mark - UIContentContainer
657   -
658   -- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
659   - [self willInterfaceOrientionChange];
660   - if (size.width > size.height) {
661   - _cropRect = _cropRectLandscape;
662   - } else {
663   - _cropRect = _cropRectPortrait;
664   - }
665   -}
666   -
667   -- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
668   - [self willInterfaceOrientionChange];
669   - if (toInterfaceOrientation >= 3) {
670   - _cropRect = _cropRectLandscape;
671   - } else {
672   - _cropRect = _cropRectPortrait;
673   - }
674   -}
675   -
676   -- (void)willInterfaceOrientionChange {
677   - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.02 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
678   - if (![UIApplication sharedApplication].statusBarHidden) {
679   - if (iOS7Later && self.needShowStatusBar) [UIApplication sharedApplication].statusBarHidden = NO;
680   - }
681   - });
682   -}
683   -
684   -#pragma mark - Layout
685   -
686   -- (void)viewDidLayoutSubviews {
687   - [super viewDidLayoutSubviews];
688   -
689   - _HUDContainer.frame = CGRectMake((self.view.tz_width - 120) / 2, (self.view.tz_height - 90) / 2, 120, 90);
690   - _HUDIndicatorView.frame = CGRectMake(45, 15, 30, 30);
691   - _HUDLabel.frame = CGRectMake(0,40, 120, 50);
692   -}
693   -
694   -#pragma mark - Public
695   -
696   -- (void)cancelButtonClick {
697   - if (self.autoDismiss) {
698   - [self dismissViewControllerAnimated:YES completion:^{
699   - [self callDelegateMethod];
700   - }];
701   - } else {
702   - [self callDelegateMethod];
703   - }
704   -}
705   -
706   -- (void)callDelegateMethod {
707   - if ([self.pickerDelegate respondsToSelector:@selector(tz_imagePickerControllerDidCancel:)]) {
708   - [self.pickerDelegate tz_imagePickerControllerDidCancel:self];
709   - }
710   - if (self.imagePickerControllerDidCancelHandle) {
711   - self.imagePickerControllerDidCancelHandle();
712   - }
713   -}
714   -
715   -@end
716   -
717   -
718   -@interface TZAlbumPickerController ()<UITableViewDataSource,UITableViewDelegate> {
719   - UITableView *_tableView;
720   -}
721   -@property (nonatomic, strong) NSMutableArray *albumArr;
722   -@end
723   -
724   -@implementation TZAlbumPickerController
725   -
726   -- (void)viewDidLoad {
727   - [super viewDidLoad];
728   - self.isFirstAppear = YES;
729   - self.view.backgroundColor = [UIColor whiteColor];
730   -
731   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
732   - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:imagePickerVc.cancelBtnTitleStr style:UIBarButtonItemStylePlain target:imagePickerVc action:@selector(cancelButtonClick)];
733   -}
734   -
735   -- (void)viewWillAppear:(BOOL)animated {
736   - [super viewWillAppear:animated];
737   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
738   - [imagePickerVc hideProgressHUD];
739   - if (imagePickerVc.allowPickingImage) {
740   - self.navigationItem.title = [NSBundle tz_localizedStringForKey:@"Photos"];
741   - } else if (imagePickerVc.allowPickingVideo) {
742   - self.navigationItem.title = [NSBundle tz_localizedStringForKey:@"Videos"];
743   - }
744   -
745   - if (self.isFirstAppear && !imagePickerVc.navLeftBarButtonSettingBlock) {
746   - self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:[NSBundle tz_localizedStringForKey:@"Back"] style:UIBarButtonItemStylePlain target:nil action:nil];
747   - }
748   -
749   - [self configTableView];
750   -}
751   -
752   -- (void)configTableView {
753   - if (![[TZImageManager manager] authorizationStatusAuthorized]) {
754   - return;
755   - }
756   -
757   - if (self.isFirstAppear) {
758   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
759   - [imagePickerVc showProgressHUD];
760   - }
761   -
762   - dispatch_async(dispatch_get_global_queue(0, 0), ^{
763   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
764   - [[TZImageManager manager] getAllAlbums:imagePickerVc.allowPickingVideo allowPickingImage:imagePickerVc.allowPickingImage needFetchAssets:!self.isFirstAppear completion:^(NSArray<TZAlbumModel *> *models) {
765   - dispatch_async(dispatch_get_main_queue(), ^{
766   - self->_albumArr = [NSMutableArray arrayWithArray:models];
767   - for (TZAlbumModel *albumModel in self->_albumArr) {
768   - albumModel.selectedModels = imagePickerVc.selectedModels;
769   - }
770   - [imagePickerVc hideProgressHUD];
771   -
772   - if (self.isFirstAppear) {
773   - self.isFirstAppear = NO;
774   - [self configTableView];
775   - }
776   -
777   - if (!self->_tableView) {
778   - self->_tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
779   - self->_tableView.rowHeight = 70;
780   - self->_tableView.tableFooterView = [[UIView alloc] init];
781   - self->_tableView.dataSource = self;
782   - self->_tableView.delegate = self;
783   - [self->_tableView registerClass:[TZAlbumCell class] forCellReuseIdentifier:@"TZAlbumCell"];
784   - [self.view addSubview:self->_tableView];
785   - } else {
786   - [self->_tableView reloadData];
787   - }
788   - });
789   - }];
790   - });
791   -}
792   -
793   -- (void)dealloc {
794   - // NSLog(@"%@ dealloc",NSStringFromClass(self.class));
795   -}
796   -
797   -#pragma mark - Layout
798   -
799   -- (void)viewDidLayoutSubviews {
800   - [super viewDidLayoutSubviews];
801   -
802   - CGFloat top = 0;
803   - CGFloat tableViewHeight = 0;
804   - CGFloat naviBarHeight = self.navigationController.navigationBar.tz_height;
805   - BOOL isStatusBarHidden = [UIApplication sharedApplication].isStatusBarHidden;
806   - if (self.navigationController.navigationBar.isTranslucent) {
807   - top = naviBarHeight;
808   - if (iOS7Later && !isStatusBarHidden) top += [TZCommonTools tz_statusBarHeight];
809   - tableViewHeight = self.view.tz_height - top;
810   - } else {
811   - tableViewHeight = self.view.tz_height;
812   - }
813   - _tableView.frame = CGRectMake(0, top, self.view.tz_width, tableViewHeight);
814   -}
815   -
816   -#pragma mark - UITableViewDataSource && Delegate
817   -
818   -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
819   - return _albumArr.count;
820   -}
821   -
822   -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
823   - TZAlbumCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TZAlbumCell"];
824   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
825   - cell.albumCellDidLayoutSubviewsBlock = imagePickerVc.albumCellDidLayoutSubviewsBlock;
826   - cell.albumCellDidSetModelBlock = imagePickerVc.albumCellDidSetModelBlock;
827   - cell.selectedCountButton.backgroundColor = imagePickerVc.iconThemeColor;
828   - cell.model = _albumArr[indexPath.row];
829   - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
830   - return cell;
831   -}
832   -
833   -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
834   - TZPhotoPickerController *photoPickerVc = [[TZPhotoPickerController alloc] init];
835   - photoPickerVc.columnNumber = self.columnNumber;
836   - TZAlbumModel *model = _albumArr[indexPath.row];
837   - photoPickerVc.model = model;
838   - [self.navigationController pushViewController:photoPickerVc animated:YES];
839   - [tableView deselectRowAtIndexPath:indexPath animated:NO];
840   -}
841   -
842   -#pragma clang diagnostic pop
843   -
844   -@end
845   -
846   -
847   -@implementation UIImage (MyBundle)
848   -
849   -+ (UIImage *)imageNamedFromMyBundle:(NSString *)name {
850   - NSBundle *imageBundle = [NSBundle tz_imagePickerBundle];
851   - name = [name stringByAppendingString:@"@2x"];
852   - NSString *imagePath = [imageBundle pathForResource:name ofType:@"png"];
853   - UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
854   - if (!image) {
855   - // 兼容业务方自己设置图片的方式
856   - name = [name stringByReplacingOccurrencesOfString:@"@2x" withString:@""];
857   - image = [UIImage imageNamed:name];
858   - }
859   - return image;
860   -}
861   -
862   -@end
863   -
864   -
865   -@implementation NSString (TzExtension)
866   -
867   -- (BOOL)tz_containsString:(NSString *)string {
868   - if (iOS8Later) {
869   - return [self containsString:string];
870   - } else {
871   - NSRange range = [self rangeOfString:string];
872   - return range.location != NSNotFound;
873   - }
874   -}
875   -
876   -#pragma clang diagnostic push
877   -#pragma clang diagnostic ignored "-Wdeprecated-declarations"
878   -- (CGSize)tz_calculateSizeWithAttributes:(NSDictionary *)attributes maxSize:(CGSize)maxSize {
879   - CGSize size;
880   - if (iOS7Later) {
881   - size = [self boundingRectWithSize:maxSize options:NSStringDrawingUsesFontLeading attributes:attributes context:nil].size;
882   - } else {
883   - size = [self sizeWithFont:attributes[NSFontAttributeName] constrainedToSize:maxSize];
884   - }
885   - return size;
886   -}
887   -#pragma clang diagnostic pop
888   -
889   -@end
890   -
891   -
892   -@implementation TZCommonTools
893   -
894   -+ (BOOL)tz_isIPhoneX {
895   - return (CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(375, 812)) ||CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(812, 375)) ||CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(414, 896)) ||CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(896, 414)));
896   -}
897   -
898   -+ (CGFloat)tz_statusBarHeight {
899   - return [self tz_isIPhoneX] ? 44 : 20;
900   -}
901   -
902   -// 获得Info.plist数据字典
903   -+ (NSDictionary *)tz_getInfoDictionary {
904   - NSDictionary *infoDict = [NSBundle mainBundle].localizedInfoDictionary;
905   - if (!infoDict || !infoDict.count) {
906   - infoDict = [NSBundle mainBundle].infoDictionary;
907   - }
908   - if (!infoDict || !infoDict.count) {
909   - NSString *path = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
910   - infoDict = [NSDictionary dictionaryWithContentsOfFile:path];
911   - }
912   - return infoDict ? infoDict : @{};
913   -}
914   -@end
915   -
916   -
917   -@implementation TZImagePickerConfig
918   -
919   -+ (instancetype)sharedInstance {
920   - static dispatch_once_t onceToken;
921   - static TZImagePickerConfig *config = nil;
922   - dispatch_once(&onceToken, ^{
923   - if (config == nil) {
924   - config = [[TZImagePickerConfig alloc] init];
925   - config.preferredLanguage = nil;
926   - config.gifPreviewMaxImagesCount = 200;
927   - }
928   - });
929   - return config;
930   -}
931   -
932   -- (void)setPreferredLanguage:(NSString *)preferredLanguage {
933   - _preferredLanguage = preferredLanguage;
934   -
935   - if (!preferredLanguage || !preferredLanguage.length) {
936   - preferredLanguage = [NSLocale preferredLanguages].firstObject;
937   - }
938   - if ([preferredLanguage rangeOfString:@"zh-Hans"].location != NSNotFound) {
939   - preferredLanguage = @"zh-Hans";
940   - } else if ([preferredLanguage rangeOfString:@"zh-Hant"].location != NSNotFound) {
941   - preferredLanguage = @"zh-Hant";
942   - } else if ([preferredLanguage rangeOfString:@"vi"].location != NSNotFound) {
943   - preferredLanguage = @"vi";
944   - } else {
945   - preferredLanguage = @"en";
946   - }
947   - _languageBundle = [NSBundle bundleWithPath:[[NSBundle tz_imagePickerBundle] pathForResource:preferredLanguage ofType:@"lproj"]];
948   -}
949   -
950   -@end
CNLiveImagePickerController/TZLocationManager.h deleted 100755 → 0
1   -//
2   -// TZLocationManager.h
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 2017/06/03.
6   -// Copyright © 2017年 谭真. All rights reserved.
7   -// 定位管理类
8   -
9   -
10   -#import <Foundation/Foundation.h>
11   -#import <CoreLocation/CoreLocation.h>
12   -
13   -@interface TZLocationManager : NSObject
14   -
15   -+ (instancetype)manager;
16   -
17   -/// 开始定位
18   -- (void)startLocation;
19   -- (void)startLocationWithSuccessBlock:(void (^)(NSArray<CLLocation *> *))successBlock failureBlock:(void (^)(NSError *error))failureBlock;
20   -- (void)startLocationWithGeocoderBlock:(void (^)(NSArray *geocoderArray))geocoderBlock;
21   -- (void)startLocationWithSuccessBlock:(void (^)(NSArray<CLLocation *> *))successBlock failureBlock:(void (^)(NSError *error))failureBlock geocoderBlock:(void (^)(NSArray *geocoderArray))geocoderBlock;
22   -
23   -@end
24   -
CNLiveImagePickerController/TZLocationManager.m deleted 100755 → 0
1   -//
2   -// TZLocationManager.m
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 2017/06/03.
6   -// Copyright © 2017年 谭真. All rights reserved.
7   -// 定位管理类
8   -
9   -#import "TZLocationManager.h"
10   -#import "TZImagePickerController.h"
11   -
12   -@interface TZLocationManager ()<CLLocationManagerDelegate>
13   -@property (nonatomic, strong) CLLocationManager *locationManager;
14   -/// 定位成功的回调block
15   -@property (nonatomic, copy) void (^successBlock)(NSArray<CLLocation *> *);
16   -/// 编码成功的回调block
17   -@property (nonatomic, copy) void (^geocodeBlock)(NSArray *geocodeArray);
18   -/// 定位失败的回调block
19   -@property (nonatomic, copy) void (^failureBlock)(NSError *error);
20   -@end
21   -
22   -@implementation TZLocationManager
23   -
24   -+ (instancetype)manager {
25   - static TZLocationManager *manager;
26   - static dispatch_once_t onceToken;
27   - dispatch_once(&onceToken, ^{
28   - manager = [[self alloc] init];
29   - manager.locationManager = [[CLLocationManager alloc] init];
30   - manager.locationManager.delegate = manager;
31   - if (iOS8Later) {
32   - [manager.locationManager requestWhenInUseAuthorization];
33   - }
34   - });
35   - return manager;
36   -}
37   -
38   -- (void)startLocation {
39   - [self startLocationWithSuccessBlock:nil failureBlock:nil geocoderBlock:nil];
40   -}
41   -
42   -- (void)startLocationWithSuccessBlock:(void (^)(NSArray<CLLocation *> *))successBlock failureBlock:(void (^)(NSError *error))failureBlock {
43   - [self startLocationWithSuccessBlock:successBlock failureBlock:failureBlock geocoderBlock:nil];
44   -}
45   -
46   -- (void)startLocationWithGeocoderBlock:(void (^)(NSArray *geocoderArray))geocoderBlock {
47   - [self startLocationWithSuccessBlock:nil failureBlock:nil geocoderBlock:geocoderBlock];
48   -}
49   -
50   -- (void)startLocationWithSuccessBlock:(void (^)(NSArray<CLLocation *> *))successBlock failureBlock:(void (^)(NSError *error))failureBlock geocoderBlock:(void (^)(NSArray *geocoderArray))geocoderBlock {
51   - [self.locationManager startUpdatingLocation];
52   - _successBlock = successBlock;
53   - _geocodeBlock = geocoderBlock;
54   - _failureBlock = failureBlock;
55   -}
56   -
57   -#pragma mark - CLLocationManagerDelegate
58   -
59   -/// 地理位置发生改变时触发
60   -- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
61   - [manager stopUpdatingLocation];
62   -
63   - if (_successBlock) {
64   - _successBlock(locations);
65   - }
66   -
67   - if (_geocodeBlock && locations.count) {
68   - CLGeocoder *geocoder = [[CLGeocoder alloc] init];
69   - [geocoder reverseGeocodeLocation:[locations firstObject] completionHandler:^(NSArray *array, NSError *error) {
70   - self->_geocodeBlock(array);
71   - }];
72   - }
73   -}
74   -
75   -/// 定位失败回调方法
76   -- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
77   - NSLog(@"定位失败, 错误: %@",error);
78   - switch([error code]) {
79   - case kCLErrorDenied: { // 用户禁止了定位权限
80   -
81   - } break;
82   - default: break;
83   - }
84   - if (_failureBlock) {
85   - _failureBlock(error);
86   - }
87   -}
88   -
89   -@end
CNLiveImagePickerController/TZPhotoPickerController.h deleted 100755 → 0
1   -//
2   -// TZPhotoPickerController.h
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 15/12/24.
6   -// Copyright © 2015年 谭真. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -@class TZAlbumModel;
12   -@interface TZPhotoPickerController : UIViewController
13   -
14   -@property (nonatomic, assign) BOOL isFirstAppear;
15   -@property (nonatomic, assign) NSInteger columnNumber;
16   -@property (nonatomic, strong) TZAlbumModel *model;
17   -@end
18   -
19   -
20   -@interface TZCollectionView : UICollectionView
21   -
22   -@end
CNLiveImagePickerController/TZPhotoPickerController.m deleted 100755 → 0
1   -//
2   -// TZPhotoPickerController.m
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 15/12/24.
6   -// Copyright © 2015年 谭真. All rights reserved.
7   -//
8   -
9   -#import "TZPhotoPickerController.h"
10   -#import "TZImagePickerController.h"
11   -#import "TZPhotoPreviewController.h"
12   -#import "TZAssetCell.h"
13   -#import "TZAssetModel.h"
14   -#import "UIView+Layout.h"
15   -#import "TZImageManager.h"
16   -#import "TZVideoPlayerController.h"
17   -#import "TZGifPhotoPreviewController.h"
18   -#import "TZLocationManager.h"
19   -#import <MobileCoreServices/MobileCoreServices.h>
20   -#import <AssetsLibrary/AssetsLibrary.h>///lxg
21   -
22   -@interface TZPhotoPickerController ()<UICollectionViewDataSource,UICollectionViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIAlertViewDelegate> {
23   - NSMutableArray *_models;
24   -
25   - UIView *_bottomToolBar;
26   - UIButton *_previewButton;
27   - UIButton *_doneButton;
28   - UIImageView *_numberImageView;
29   - UILabel *_numberLabel;
30   - UIButton *_originalPhotoButton;
31   - UILabel *_originalPhotoLabel;
32   - UIView *_divideLine;
33   -
34   - BOOL _shouldScrollToBottom;
35   - BOOL _showTakePhotoBtn;
36   -
37   - CGFloat _offsetItemCount;
38   -
39   - BOOL _isClickDone;///防止多次点击(LXG)
40   -}
41   -@property CGRect previousPreheatRect;
42   -@property (nonatomic, assign) BOOL isSelectOriginalPhoto;
43   -@property (nonatomic, strong) TZCollectionView *collectionView;
44   -@property (strong, nonatomic) UICollectionViewFlowLayout *layout;
45   -@property (nonatomic, strong) UIImagePickerController *imagePickerVc;
46   -@property (strong, nonatomic) CLLocation *location;
47   -@property (assign, nonatomic) BOOL useCachedImage;
48   -@end
49   -
50   -static CGSize AssetGridThumbnailSize;
51   -static CGFloat itemMargin = 5;
52   -
53   -@implementation TZPhotoPickerController
54   -
55   -#pragma clang diagnostic push
56   -#pragma clang diagnostic ignored "-Wdeprecated-declarations"
57   -- (UIImagePickerController *)imagePickerVc {
58   - if (_imagePickerVc == nil) {
59   - _imagePickerVc = [[UIImagePickerController alloc] init];
60   - _imagePickerVc.delegate = self;
61   - // set appearance / 改变相册选择页的导航栏外观
62   - if (iOS7Later) {
63   - _imagePickerVc.navigationBar.barTintColor = self.navigationController.navigationBar.barTintColor;
64   - }
65   - _imagePickerVc.navigationBar.tintColor = self.navigationController.navigationBar.tintColor;
66   - UIBarButtonItem *tzBarItem, *BarItem;
67   - if (@available(iOS 9, *)) {
68   - tzBarItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[TZImagePickerController class]]];
69   - BarItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UIImagePickerController class]]];
70   - } else {
71   - tzBarItem = [UIBarButtonItem appearanceWhenContainedIn:[TZImagePickerController class], nil];
72   - BarItem = [UIBarButtonItem appearanceWhenContainedIn:[UIImagePickerController class], nil];
73   - }
74   - NSDictionary *titleTextAttributes = [tzBarItem titleTextAttributesForState:UIControlStateNormal];
75   - [BarItem setTitleTextAttributes:titleTextAttributes forState:UIControlStateNormal];
76   - }
77   - return _imagePickerVc;
78   -}
79   -
80   -- (void)viewDidLoad {
81   - [super viewDidLoad];
82   - _isClickDone = NO;
83   - self.isFirstAppear = YES;
84   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
85   - _isSelectOriginalPhoto = tzImagePickerVc.isSelectOriginalPhoto;
86   - _shouldScrollToBottom = YES;
87   - self.view.backgroundColor = [UIColor whiteColor];
88   - self.navigationItem.title = _model.name;
89   - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:tzImagePickerVc.cancelBtnTitleStr style:UIBarButtonItemStylePlain target:tzImagePickerVc action:@selector(cancelButtonClick)];
90   - if (tzImagePickerVc.navLeftBarButtonSettingBlock) {
91   - UIButton *leftButton = [UIButton buttonWithType:UIButtonTypeCustom];
92   - leftButton.frame = CGRectMake(0, 0, 44, 44);
93   - [leftButton addTarget:self action:@selector(navLeftBarButtonClick) forControlEvents:UIControlEventTouchUpInside];
94   - tzImagePickerVc.navLeftBarButtonSettingBlock(leftButton);
95   - self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:leftButton];
96   - } else if (tzImagePickerVc.childViewControllers.count) {
97   - [tzImagePickerVc.childViewControllers firstObject].navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:[NSBundle tz_localizedStringForKey:@"Back"] style:UIBarButtonItemStylePlain target:nil action:nil];
98   - }
99   - _showTakePhotoBtn = _model.isCameraRoll && ((tzImagePickerVc.allowTakePicture && tzImagePickerVc.allowPickingImage) || (tzImagePickerVc.allowTakeVideo && tzImagePickerVc.allowPickingVideo));
100   - // [self resetCachedAssets];
101   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeStatusBarOrientationNotification:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
102   -}
103   -
104   -- (void)fetchAssetModels {
105   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
106   - if (_isFirstAppear && !_model.models.count) {
107   - [tzImagePickerVc showProgressHUD];
108   - }
109   - dispatch_async(dispatch_get_global_queue(0, 0), ^{
110   - if (!tzImagePickerVc.sortAscendingByModificationDate && self->_isFirstAppear && iOS8Later && self->_model.isCameraRoll) {
111   - [[TZImageManager manager] getCameraRollAlbum:tzImagePickerVc.allowPickingVideo allowPickingImage:tzImagePickerVc.allowPickingImage needFetchAssets:YES completion:^(TZAlbumModel *model) {
112   - self->_model = model;
113   - self->_models = [NSMutableArray arrayWithArray:self->_model.models];
114   - [self initSubviews];
115   - }];
116   - } else {
117   - if (self->_showTakePhotoBtn || !iOS8Later || self->_isFirstAppear) {
118   - [[TZImageManager manager] getAssetsFromFetchResult:self->_model.result completion:^(NSArray<TZAssetModel *> *models) {
119   - self->_models = [NSMutableArray arrayWithArray:models];
120   - [self initSubviews];
121   - }];
122   - } else {
123   - self->_models = [NSMutableArray arrayWithArray:self->_model.models];
124   - [self initSubviews];
125   - }
126   - }
127   - });
128   -}
129   -
130   -- (void)initSubviews {
131   - dispatch_async(dispatch_get_main_queue(), ^{
132   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
133   - [tzImagePickerVc hideProgressHUD];
134   -
135   - [self checkSelectedModels];
136   - [self configCollectionView];
137   - self->_collectionView.hidden = YES;
138   - [self configBottomToolBar];
139   -
140   - [self scrollCollectionViewToBottom];
141   - });
142   -}
143   -
144   -- (void)viewWillDisappear:(BOOL)animated {
145   - [super viewWillDisappear:animated];
146   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
147   - tzImagePickerVc.isSelectOriginalPhoto = _isSelectOriginalPhoto;
148   -}
149   -
150   -- (BOOL)prefersStatusBarHidden {
151   - return NO;
152   -}
153   -
154   -- (void)configCollectionView {
155   - _layout = [[UICollectionViewFlowLayout alloc] init];
156   - _collectionView = [[TZCollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:_layout];
157   - _collectionView.backgroundColor = [UIColor whiteColor];
158   - _collectionView.dataSource = self;
159   - _collectionView.delegate = self;
160   - _collectionView.alwaysBounceHorizontal = NO;
161   - _collectionView.contentInset = UIEdgeInsetsMake(itemMargin, itemMargin, itemMargin, itemMargin);
162   -
163   - if (_showTakePhotoBtn) {
164   - _collectionView.contentSize = CGSizeMake(self.view.tz_width, ((_model.count + self.columnNumber) / self.columnNumber) * self.view.tz_width);
165   - } else {
166   - _collectionView.contentSize = CGSizeMake(self.view.tz_width, ((_model.count + self.columnNumber - 1) / self.columnNumber) * self.view.tz_width);
167   - }
168   - [self.view addSubview:_collectionView];
169   - [_collectionView registerClass:[TZAssetCell class] forCellWithReuseIdentifier:@"TZAssetCell"];
170   - [_collectionView registerClass:[TZAssetCameraCell class] forCellWithReuseIdentifier:@"TZAssetCameraCell"];
171   -}
172   -
173   -- (void)viewWillAppear:(BOOL)animated {
174   - [super viewWillAppear:animated];
175   - // Determine the size of the thumbnails to request from the PHCachingImageManager
176   - CGFloat scale = 2.0;
177   - if ([UIScreen mainScreen].bounds.size.width > 600) {
178   - scale = 1.0;
179   - }
180   - CGSize cellSize = ((UICollectionViewFlowLayout *)_collectionView.collectionViewLayout).itemSize;
181   - AssetGridThumbnailSize = CGSizeMake(cellSize.width * scale, cellSize.height * scale);
182   -
183   - if (!_models) {
184   - [self fetchAssetModels];
185   - }
186   -}
187   -
188   -- (void)viewDidAppear:(BOOL)animated {
189   - [super viewDidAppear:animated];
190   - if (iOS8Later) {
191   - // [self updateCachedAssets];
192   - }
193   -}
194   -
195   -- (void)configBottomToolBar {
196   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
197   - if (!tzImagePickerVc.showSelectBtn) return;
198   -
199   - _bottomToolBar = [[UIView alloc] initWithFrame:CGRectZero];
200   - CGFloat rgb = 253 / 255.0;
201   - _bottomToolBar.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:1.0];
202   -
203   - _previewButton = [UIButton buttonWithType:UIButtonTypeCustom];
204   - [_previewButton addTarget:self action:@selector(previewButtonClick) forControlEvents:UIControlEventTouchUpInside];
205   - _previewButton.titleLabel.font = [UIFont systemFontOfSize:16];
206   - [_previewButton setTitle:tzImagePickerVc.previewBtnTitleStr forState:UIControlStateNormal];
207   - [_previewButton setTitle:tzImagePickerVc.previewBtnTitleStr forState:UIControlStateDisabled];
208   - [_previewButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
209   - [_previewButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled];
210   - _previewButton.enabled = tzImagePickerVc.selectedModels.count;
211   -
212   - if (tzImagePickerVc.allowPickingOriginalPhoto) {
213   - _originalPhotoButton = [UIButton buttonWithType:UIButtonTypeCustom];
214   - _originalPhotoButton.imageEdgeInsets = UIEdgeInsetsMake(0, -10, 0, 0);
215   - [_originalPhotoButton addTarget:self action:@selector(originalPhotoButtonClick) forControlEvents:UIControlEventTouchUpInside];
216   - _originalPhotoButton.titleLabel.font = [UIFont systemFontOfSize:16];
217   - [_originalPhotoButton setTitle:tzImagePickerVc.fullImageBtnTitleStr forState:UIControlStateNormal];
218   - [_originalPhotoButton setTitle:tzImagePickerVc.fullImageBtnTitleStr forState:UIControlStateSelected];
219   - [_originalPhotoButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
220   - [_originalPhotoButton setTitleColor:[UIColor blackColor] forState:UIControlStateSelected];
221   - [_originalPhotoButton setImage:tzImagePickerVc.photoOriginDefImage forState:UIControlStateNormal];
222   - [_originalPhotoButton setImage:tzImagePickerVc.photoOriginSelImage forState:UIControlStateSelected];
223   - _originalPhotoButton.imageView.clipsToBounds = YES;
224   - _originalPhotoButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
225   - _originalPhotoButton.selected = _isSelectOriginalPhoto;
226   - _originalPhotoButton.enabled = tzImagePickerVc.selectedModels.count > 0;
227   -
228   - _originalPhotoLabel = [[UILabel alloc] init];
229   - _originalPhotoLabel.textAlignment = NSTextAlignmentLeft;
230   - _originalPhotoLabel.font = [UIFont systemFontOfSize:16];
231   - _originalPhotoLabel.textColor = [UIColor blackColor];
232   - if (_isSelectOriginalPhoto) [self getSelectedPhotoBytes];
233   - }
234   -
235   - _doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
236   - _doneButton.titleLabel.font = [UIFont systemFontOfSize:16];
237   - [_doneButton addTarget:self action:@selector(doneButtonClick) forControlEvents:UIControlEventTouchUpInside];
238   - [_doneButton setTitle:tzImagePickerVc.doneBtnTitleStr forState:UIControlStateNormal];
239   - [_doneButton setTitle:tzImagePickerVc.doneBtnTitleStr forState:UIControlStateDisabled];
240   - [_doneButton setTitleColor:tzImagePickerVc.oKButtonTitleColorNormal forState:UIControlStateNormal];
241   - [_doneButton setTitleColor:tzImagePickerVc.oKButtonTitleColorDisabled forState:UIControlStateDisabled];
242   - _doneButton.enabled = tzImagePickerVc.selectedModels.count || tzImagePickerVc.alwaysEnableDoneBtn;
243   -
244   - _numberImageView = [[UIImageView alloc] initWithImage:tzImagePickerVc.photoNumberIconImage];
245   - _numberImageView.hidden = tzImagePickerVc.selectedModels.count <= 0;
246   - _numberImageView.clipsToBounds = YES;
247   - _numberImageView.contentMode = UIViewContentModeScaleAspectFit;
248   - _numberImageView.backgroundColor = [UIColor clearColor];
249   -
250   - _numberLabel = [[UILabel alloc] init];
251   - _numberLabel.font = [UIFont systemFontOfSize:15];
252   - _numberLabel.textColor = [UIColor whiteColor];
253   - _numberLabel.textAlignment = NSTextAlignmentCenter;
254   - _numberLabel.text = [NSString stringWithFormat:@"%zd",tzImagePickerVc.selectedModels.count];
255   - _numberLabel.hidden = tzImagePickerVc.selectedModels.count <= 0;
256   - _numberLabel.backgroundColor = [UIColor clearColor];
257   -#pragma mark - ADD: 选择图片个数显示(LXG)
258   - _numberImageView.hidden = YES;
259   - _numberLabel.hidden = YES;
260   - [_doneButton setTitle:[NSString stringWithFormat:@"完成(%zd)",tzImagePickerVc.selectedModels.count] forState:UIControlStateNormal];
261   -
262   - _divideLine = [[UIView alloc] init];
263   - CGFloat rgb2 = 222 / 255.0;
264   - _divideLine.backgroundColor = [UIColor colorWithRed:rgb2 green:rgb2 blue:rgb2 alpha:1.0];
265   -
266   - [_bottomToolBar addSubview:_divideLine];
267   - [_bottomToolBar addSubview:_previewButton];
268   - [_bottomToolBar addSubview:_doneButton];
269   - [_bottomToolBar addSubview:_numberImageView];
270   - [_bottomToolBar addSubview:_numberLabel];
271   - [_bottomToolBar addSubview:_originalPhotoButton];
272   - [self.view addSubview:_bottomToolBar];
273   - [_originalPhotoButton addSubview:_originalPhotoLabel];
274   -
275   - if (tzImagePickerVc.photoPickerPageUIConfigBlock) {
276   - tzImagePickerVc.photoPickerPageUIConfigBlock(_collectionView, _bottomToolBar, _previewButton, _originalPhotoButton, _originalPhotoLabel, _doneButton, _numberImageView, _numberLabel, _divideLine);
277   - }
278   -}
279   -
280   -#pragma mark - Layout
281   -
282   -- (void)viewDidLayoutSubviews {
283   - [super viewDidLayoutSubviews];
284   -
285   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
286   -
287   - CGFloat top = 0;
288   - CGFloat collectionViewHeight = 0;
289   - CGFloat naviBarHeight = self.navigationController.navigationBar.tz_height;
290   - BOOL isStatusBarHidden = [UIApplication sharedApplication].isStatusBarHidden;
291   - CGFloat toolBarHeight = [TZCommonTools tz_isIPhoneX] ? 50 + (83 - 49) : 50;
292   - if (self.navigationController.navigationBar.isTranslucent) {
293   - top = naviBarHeight;
294   - if (iOS7Later && !isStatusBarHidden) top += [TZCommonTools tz_statusBarHeight];
295   - collectionViewHeight = tzImagePickerVc.showSelectBtn ? self.view.tz_height - toolBarHeight - top : self.view.tz_height - top;;
296   - } else {
297   - collectionViewHeight = tzImagePickerVc.showSelectBtn ? self.view.tz_height - toolBarHeight : self.view.tz_height;
298   - }
299   - _collectionView.frame = CGRectMake(0, top, self.view.tz_width, collectionViewHeight);
300   - CGFloat itemWH = (self.view.tz_width - (self.columnNumber + 1) * itemMargin) / self.columnNumber;
301   - _layout.itemSize = CGSizeMake(itemWH, itemWH);
302   - _layout.minimumInteritemSpacing = itemMargin;
303   - _layout.minimumLineSpacing = itemMargin;
304   - [_collectionView setCollectionViewLayout:_layout];
305   - if (_offsetItemCount > 0) {
306   - CGFloat offsetY = _offsetItemCount * (_layout.itemSize.height + _layout.minimumLineSpacing);
307   - [_collectionView setContentOffset:CGPointMake(0, offsetY)];
308   - }
309   -
310   - CGFloat toolBarTop = 0;
311   - if (!self.navigationController.navigationBar.isHidden) {
312   - toolBarTop = self.view.tz_height - toolBarHeight;
313   - } else {
314   - CGFloat navigationHeight = naviBarHeight;
315   - if (iOS7Later) navigationHeight += [TZCommonTools tz_statusBarHeight];
316   - toolBarTop = self.view.tz_height - toolBarHeight - navigationHeight;
317   - }
318   - _bottomToolBar.frame = CGRectMake(0, toolBarTop, self.view.tz_width, toolBarHeight);
319   - CGFloat previewWidth = [tzImagePickerVc.previewBtnTitleStr tz_calculateSizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:16]} maxSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)].width + 2;
320   - if (!tzImagePickerVc.allowPreview) {
321   - previewWidth = 0.0;
322   - }
323   - _previewButton.frame = CGRectMake(10, 3, previewWidth, 44);
324   - _previewButton.tz_width = !tzImagePickerVc.showSelectBtn ? 0 : previewWidth;
325   - if (tzImagePickerVc.allowPickingOriginalPhoto) {
326   - CGFloat fullImageWidth = [tzImagePickerVc.fullImageBtnTitleStr tz_calculateSizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:13]} maxSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)].width;
327   - _originalPhotoButton.frame = CGRectMake(CGRectGetMaxX(_previewButton.frame), 0, fullImageWidth + 56, 50);
328   - _originalPhotoLabel.frame = CGRectMake(fullImageWidth + 46, 0, 80, 50);
329   - }
330   - [_doneButton sizeToFit];
331   - _doneButton.frame = CGRectMake(self.view.tz_width - _doneButton.tz_width - 12, 0, _doneButton.tz_width, 50);
332   - _numberImageView.frame = CGRectMake(_doneButton.tz_left - 24 - 5, 13, 24, 24);
333   - _numberLabel.frame = _numberImageView.frame;
334   - _divideLine.frame = CGRectMake(0, 0, self.view.tz_width, 1);
335   -
336   - [TZImageManager manager].columnNumber = [TZImageManager manager].columnNumber;
337   - [self.collectionView reloadData];
338   -
339   - if (tzImagePickerVc.photoPickerPageDidLayoutSubviewsBlock) {
340   - tzImagePickerVc.photoPickerPageDidLayoutSubviewsBlock(_collectionView, _bottomToolBar, _previewButton, _originalPhotoButton, _originalPhotoLabel, _doneButton, _numberImageView, _numberLabel, _divideLine);
341   - }
342   -}
343   -
344   -#pragma mark - Notification
345   -
346   -- (void)didChangeStatusBarOrientationNotification:(NSNotification *)noti {
347   - _offsetItemCount = _collectionView.contentOffset.y / (_layout.itemSize.height + _layout.minimumLineSpacing);
348   -}
349   -
350   -#pragma mark - Click Event
351   -- (void)navLeftBarButtonClick{
352   - [self.navigationController popViewControllerAnimated:YES];
353   -}
354   -- (void)previewButtonClick {
355   - TZPhotoPreviewController *photoPreviewVc = [[TZPhotoPreviewController alloc] init];
356   - [self pushPhotoPrevireViewController:photoPreviewVc needCheckSelectedModels:YES];
357   -}
358   -
359   -- (void)originalPhotoButtonClick {
360   - _originalPhotoButton.selected = !_originalPhotoButton.isSelected;
361   - _isSelectOriginalPhoto = _originalPhotoButton.isSelected;
362   - _originalPhotoLabel.hidden = YES; ///lxg添加
363   -// _originalPhotoLabel.hidden = !_originalPhotoButton.isSelected;///lxg注释
364   - if (_isSelectOriginalPhoto) {
365   - [self getSelectedPhotoBytes];
366   - }
367   -}
368   -
369   -- (void)doneButtonClick {
370   -
371   - if (!_isClickDone) {
372   - _isClickDone = YES;
373   - }else{
374   - return;
375   - }
376   -
377   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
378   - // 1.6.8 判断是否满足最小必选张数的限制
379   - if (tzImagePickerVc.minImagesCount && tzImagePickerVc.selectedModels.count < tzImagePickerVc.minImagesCount) {
380   - NSString *title = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Select a minimum of %zd photos"], tzImagePickerVc.minImagesCount];
381   - [tzImagePickerVc showAlertWithTitle:title];
382   - return;
383   - }
384   -
385   - [tzImagePickerVc showProgressHUD];
386   - NSMutableArray *assets = [NSMutableArray array];
387   - NSMutableArray *photos;
388   - NSMutableArray *infoArr;
389   - if (tzImagePickerVc.onlyReturnAsset) { // not fetch image
390   - for (NSInteger i = 0; i < tzImagePickerVc.selectedModels.count; i++) {
391   - TZAssetModel *model = tzImagePickerVc.selectedModels[i];
392   - [assets addObject:model.asset];
393   - }
394   - } else { // fetch image
395   - photos = [NSMutableArray array];
396   - infoArr = [NSMutableArray array];
397   - for (NSInteger i = 0; i < tzImagePickerVc.selectedModels.count; i++) { [photos addObject:@1];[assets addObject:@1];[infoArr addObject:@1]; }
398   -
399   - __block BOOL havenotShowAlert = YES;
400   - [TZImageManager manager].shouldFixOrientation = YES;
401   - __block id alertView;
402   - for (NSInteger i = 0; i < tzImagePickerVc.selectedModels.count; i++) {
403   - TZAssetModel *model = tzImagePickerVc.selectedModels[i];
404   - [[TZImageManager manager] getPhotoWithAsset:model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
405   - if (isDegraded) return;
406   - if (photo) {
407   - if (![TZImagePickerConfig sharedInstance].notScaleImage) {
408   - photo = [[TZImageManager manager] scaleImage:photo toSize:CGSizeMake(tzImagePickerVc.photoWidth, (int)(tzImagePickerVc.photoWidth * photo.size.height / photo.size.width))];
409   - }
410   - [photos replaceObjectAtIndex:i withObject:photo];
411   - }
412   - if (info) [infoArr replaceObjectAtIndex:i withObject:info];
413   - [assets replaceObjectAtIndex:i withObject:model.asset];
414   -// [self getPhotoMetadataWithAsset:model.asset];
415   - for (id item in photos) { if ([item isKindOfClass:[NSNumber class]]) return; }
416   -
417   - if (havenotShowAlert) {
418   - [tzImagePickerVc hideAlertView:alertView];
419   - [self didGetAllPhotos:photos assets:assets infoArr:infoArr];
420   - }
421   - } progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
422   - // 如果图片正在从iCloud同步中,提醒用户
423   - if (progress < 1 && havenotShowAlert && !alertView) {
424   - [tzImagePickerVc hideProgressHUD];
425   - alertView = [tzImagePickerVc showAlertWithTitle:[NSBundle tz_localizedStringForKey:@"Synchronizing photos from iCloud"]];
426   - havenotShowAlert = NO;
427   - return;
428   - }
429   - if (progress >= 1) {
430   - havenotShowAlert = YES;
431   - }
432   - } networkAccessAllowed:YES];
433   - }
434   - }
435   - if (tzImagePickerVc.selectedModels.count <= 0 || tzImagePickerVc.onlyReturnAsset) {
436   - [self didGetAllPhotos:photos assets:assets infoArr:infoArr];
437   - }
438   -}
439   -
440   -//- (void)getPhotoMetadataWithAsset:(PHAsset *)asset
441   -//{
442   -// PHImageRequestOptions *request = [PHImageRequestOptions new];
443   -// request.version = PHImageRequestOptionsVersionCurrent;
444   -// request.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
445   -// request.resizeMode = PHImageRequestOptionsResizeModeNone;
446   -// request.synchronous = YES;
447   -// NSData *data1 = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"file:///var/mobile/Media/DCIM/100APPLE/IMG_0178.JPG"]];
448   -// UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"file:///var/mobile/Media/DCIM/100APPLE/1.JPG"]]];
449   -// [[PHImageManager defaultManager] requestImageDataForAsset:asset options: request resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
450   -// NSURL *url = [info valueForKey:@"PHImageFileURLKey"];
451   -// NSString *str = [url absoluteString]; //url>string
452   -// NSArray *arr = [str componentsSeparatedByString:@"/"];
453   -// NSString *imgName = [arr lastObject];
454   -// NSLog(@"imgName:%@",imgName);
455   -//
456   -// CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
457   -// if (NULL != source) {
458   -// NSDictionary * metadataDic = (NSDictionary *)CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(source, 0, NULL));
459   -// NSLog(@"metada:%@",metadataDic);
460   -// CFRelease(source);
461   -// }
462   -// }];
463   -//}
464   -
465   -- (void)didGetAllPhotos:(NSArray *)photos assets:(NSArray *)assets infoArr:(NSArray *)infoArr {
466   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
467   - [tzImagePickerVc hideProgressHUD];
468   -
469   - if (tzImagePickerVc.autoDismiss) {
470   - [self.navigationController dismissViewControllerAnimated:YES completion:^{
471   - [self callDelegateMethodWithPhotos:photos assets:assets infoArr:infoArr];
472   - }];
473   - } else {
474   - [self callDelegateMethodWithPhotos:photos assets:assets infoArr:infoArr];
475   - }
476   -}
477   -
478   -- (void)callDelegateMethodWithPhotos:(NSArray *)photos assets:(NSArray *)assets infoArr:(NSArray *)infoArr {
479   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
480   - if (tzImagePickerVc.allowPickingVideo && tzImagePickerVc.maxImagesCount == 1) {
481   - if ([[TZImageManager manager] isVideo:[assets firstObject]]) {
482   - if ([tzImagePickerVc.pickerDelegate respondsToSelector:@selector(imagePickerController:didFinishPickingVideo:sourceAssets:)]) {
483   - [tzImagePickerVc.pickerDelegate imagePickerController:tzImagePickerVc didFinishPickingVideo:[photos firstObject] sourceAssets:[assets firstObject]];
484   - }
485   - if (tzImagePickerVc.didFinishPickingVideoHandle) {
486   - tzImagePickerVc.didFinishPickingVideoHandle([photos firstObject], [assets firstObject]);
487   - }
488   - return;
489   - }
490   - }
491   -
492   - if ([tzImagePickerVc.pickerDelegate respondsToSelector:@selector(imagePickerController:didFinishPickingPhotos:sourceAssets:isSelectOriginalPhoto:)]) {
493   - [tzImagePickerVc.pickerDelegate imagePickerController:tzImagePickerVc didFinishPickingPhotos:photos sourceAssets:assets isSelectOriginalPhoto:_isSelectOriginalPhoto];
494   - }
495   - if ([tzImagePickerVc.pickerDelegate respondsToSelector:@selector(imagePickerController:didFinishPickingPhotos:sourceAssets:isSelectOriginalPhoto:infos:)]) {
496   - [tzImagePickerVc.pickerDelegate imagePickerController:tzImagePickerVc didFinishPickingPhotos:photos sourceAssets:assets isSelectOriginalPhoto:_isSelectOriginalPhoto infos:infoArr];
497   - }
498   - if (tzImagePickerVc.didFinishPickingPhotosHandle) {
499   - tzImagePickerVc.didFinishPickingPhotosHandle(photos,assets,_isSelectOriginalPhoto);
500   - }
501   - if (tzImagePickerVc.didFinishPickingPhotosWithInfosHandle) {
502   - tzImagePickerVc.didFinishPickingPhotosWithInfosHandle(photos,assets,_isSelectOriginalPhoto,infoArr);
503   - }
504   -}
505   -
506   -#pragma mark - UICollectionViewDataSource && Delegate
507   -
508   -- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
509   - if (_showTakePhotoBtn) {
510   - return _models.count + 1;
511   - }
512   - return _models.count;
513   -}
514   -
515   -- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
516   - // the cell lead to take a picture / 去拍照的cell
517   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
518   - if (((tzImagePickerVc.sortAscendingByModificationDate && indexPath.item >= _models.count) || (!tzImagePickerVc.sortAscendingByModificationDate && indexPath.item == 0)) && _showTakePhotoBtn) {
519   - TZAssetCameraCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TZAssetCameraCell" forIndexPath:indexPath];
520   - cell.imageView.image = tzImagePickerVc.takePictureImage;
521   - if ([tzImagePickerVc.takePictureImageName isEqualToString:@"takePicture80"]) {
522   - cell.imageView.contentMode = UIViewContentModeCenter;
523   - CGFloat rgb = 223 / 255.0;
524   - cell.imageView.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:1.0];
525   - } else {
526   - cell.imageView.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.500];
527   - }
528   - return cell;
529   - }
530   - // the cell dipaly photo or video / 展示照片或视频的cell
531   - TZAssetCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TZAssetCell" forIndexPath:indexPath];
532   - cell.allowPickingMultipleVideo = tzImagePickerVc.allowPickingMultipleVideo;
533   - cell.photoDefImage = tzImagePickerVc.photoDefImage;
534   - cell.photoSelImage = tzImagePickerVc.photoSelImage;
535   - cell.useCachedImage = self.useCachedImage;
536   - cell.assetCellDidSetModelBlock = tzImagePickerVc.assetCellDidSetModelBlock;
537   - cell.assetCellDidLayoutSubviewsBlock = tzImagePickerVc.assetCellDidLayoutSubviewsBlock;
538   - TZAssetModel *model;
539   - if (tzImagePickerVc.sortAscendingByModificationDate || !_showTakePhotoBtn) {
540   - model = _models[indexPath.item];
541   - } else {
542   - model = _models[indexPath.item - 1];
543   - }
544   - cell.allowPickingGif = tzImagePickerVc.allowPickingGif;
545   - cell.model = model;
546   - if (model.isSelected && tzImagePickerVc.showSelectedIndex) {
547   - NSString *assetId = [[TZImageManager manager] getAssetIdentifier:model.asset];
548   - cell.index = [tzImagePickerVc.selectedAssetIds indexOfObject:assetId] + 1;
549   - }
550   - cell.showSelectBtn = tzImagePickerVc.showSelectBtn;
551   - cell.allowPreview = tzImagePickerVc.allowPreview;
552   -
553   - if (tzImagePickerVc.selectedModels.count >= tzImagePickerVc.maxImagesCount && tzImagePickerVc.showPhotoCannotSelectLayer && !model.isSelected) {
554   - cell.cannotSelectLayerButton.backgroundColor = tzImagePickerVc.cannotSelectLayerColor;
555   - cell.cannotSelectLayerButton.hidden = NO;
556   - } else {
557   - cell.cannotSelectLayerButton.hidden = YES;
558   - }
559   -
560   - __weak typeof(cell) weakCell = cell;
561   - __weak typeof(self) weakSelf = self;
562   - __weak typeof(_numberImageView.layer) weakLayer = _numberImageView.layer;
563   - cell.didSelectPhotoBlock = ^(BOOL isSelected) {
564   - __strong typeof(weakCell) strongCell = weakCell;
565   - __strong typeof(weakSelf) strongSelf = weakSelf;
566   - __strong typeof(weakLayer) strongLayer = weakLayer;
567   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)strongSelf.navigationController;
568   - // 1. cancel select / 取消选择
569   - if (isSelected) {
570   - strongCell.selectPhotoButton.selected = NO;
571   - model.isSelected = NO;
572   - NSArray *selectedModels = [NSArray arrayWithArray:tzImagePickerVc.selectedModels];
573   - for (TZAssetModel *model_item in selectedModels) {
574   - if ([[[TZImageManager manager] getAssetIdentifier:model.asset] isEqualToString:[[TZImageManager manager] getAssetIdentifier:model_item.asset]]) {
575   - [tzImagePickerVc removeSelectedModel:model_item];
576   - break;
577   - }
578   - }
579   - [strongSelf refreshBottomToolBarStatus];
580   - if (tzImagePickerVc.showSelectedIndex || tzImagePickerVc.showPhotoCannotSelectLayer) {
581   - [strongSelf setUseCachedImageAndReloadData];
582   - }
583   - [UIView showOscillatoryAnimationWithLayer:strongLayer type:TZOscillatoryAnimationToSmaller];
584   - } else {
585   - // 2. select:check if over the maxImagesCount / 选择照片,检查是否超过了最大个数的限制
586   - if (tzImagePickerVc.selectedModels.count < tzImagePickerVc.maxImagesCount) {
587   - ///lxg禁止选中限制时长视频
588   - NSTimeInterval duration = 0.0;
589   - if ([model.asset isKindOfClass:[PHAsset class]]) {
590   - PHAsset *asset = model.asset;
591   - duration = asset.duration;
592   - }else if ([model.asset isKindOfClass:[ALAsset class]]){
593   - duration = [[model.asset valueForProperty:ALAssetPropertyDuration] doubleValue];
594   - }
595   - if (model.type == TZAssetModelMediaTypeVideo
596   - && tzImagePickerVc.allowPickingMultipleVideo
597   - && duration > tzImagePickerVc.maxVideoDuration) {//视频,支持混选,时长超过最大时长限制
598   - NSInteger minutes = tzImagePickerVc.maxVideoDuration / 60;
599   - NSInteger seconds = tzImagePickerVc.maxVideoDuration % 60;
600   - NSString *timeStr = [NSString string];
601   - if (minutes == 0) {
602   - timeStr = [NSString stringWithFormat:@"不能选择超过%li秒视频",(long)seconds];
603   - }else if (seconds == 0){
604   - timeStr = [NSString stringWithFormat:@"不能选择超过%li分视频",(long)minutes];
605   - }else{
606   - timeStr = [NSString stringWithFormat:@"不能选择超过%li分%li秒视频",(long)minutes,(long)seconds];
607   - }
608   - [tzImagePickerVc showAlertWithTitle:timeStr];
609   -
610   - return;
611   - }
612   -
613   -
614   - if (tzImagePickerVc.maxImagesCount == 1 && !tzImagePickerVc.allowPreview) {
615   - model.isSelected = YES;
616   - [tzImagePickerVc addSelectedModel:model];
617   - [strongSelf doneButtonClick];
618   - return;
619   - }
620   - strongCell.selectPhotoButton.selected = YES;
621   - model.isSelected = YES;
622   - if (tzImagePickerVc.showSelectedIndex || tzImagePickerVc.showPhotoCannotSelectLayer) {
623   - model.needOscillatoryAnimation = YES;
624   - [strongSelf setUseCachedImageAndReloadData];
625   - }
626   - [tzImagePickerVc addSelectedModel:model];
627   - [strongSelf refreshBottomToolBarStatus];
628   - [UIView showOscillatoryAnimationWithLayer:strongLayer type:TZOscillatoryAnimationToSmaller];
629   - } else {
630   - NSString *title = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Select a maximum of %zd photos"], tzImagePickerVc.maxImagesCount];
631   - [tzImagePickerVc showAlertWithTitle:title];
632   - }
633   - }
634   - };
635   - return cell;
636   -}
637   -
638   -- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
639   - // take a photo / 去拍照
640   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
641   - if (((tzImagePickerVc.sortAscendingByModificationDate && indexPath.item >= _models.count) || (!tzImagePickerVc.sortAscendingByModificationDate && indexPath.item == 0)) && _showTakePhotoBtn) {
642   - [self takePhoto]; return;
643   - }
644   - // preview phote or video / 预览照片或视频
645   - NSInteger index = indexPath.item;
646   - if (!tzImagePickerVc.sortAscendingByModificationDate && _showTakePhotoBtn) {
647   - index = indexPath.item - 1;
648   - }
649   -// TZAssetModel *model = _models[index];
650   -
651   -#pragma mark - 聊天里面进入和朋友圈中进入LXG
652   -
653   - TZPhotoPreviewController *photoPreviewVc = [[TZPhotoPreviewController alloc] init];
654   - photoPreviewVc.currentIndex = index;
655   - photoPreviewVc.models = _models;
656   - photoPreviewVc.isSelectOriginalPhoto = tzImagePickerVc.isSelectOriginalPhoto;
657   - [self pushPhotoPrevireViewController:photoPreviewVc];
658   -
659   -
660   -// ///LXG进行 注释
661   -// if (model.type == TZAssetModelMediaTypeVideo && !tzImagePickerVc.allowPickingMultipleVideo) {///支持混选+点击视频
662   -// if (tzImagePickerVc.selectedModels.count > 0) {
663   -// TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
664   -// [imagePickerVc showAlertWithTitle:[NSBundle tz_localizedStringForKey:@"Can not choose both video and photo"]];
665   -// } else {
666   -// TZVideoPlayerController *videoPlayerVc = [[TZVideoPlayerController alloc] init];
667   -// videoPlayerVc.model = model;
668   -// videoPlayerVc.isOther = NO;//相册内部进入(LXG)
669   -// [self.navigationController pushViewController:videoPlayerVc animated:YES];
670   -// }
671   -// } else if (model.type == TZAssetModelMediaTypePhotoGif && tzImagePickerVc.allowPickingGif && !tzImagePickerVc.allowPickingMultipleVideo) {//支持混选+GIF
672   -// if (tzImagePickerVc.selectedModels.count > 0) {
673   -// TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
674   -// [imagePickerVc showAlertWithTitle:[NSBundle tz_localizedStringForKey:@"Can not choose both photo and GIF"]];
675   -// } else {
676   -// TZGifPhotoPreviewController *gifPreviewVc = [[TZGifPhotoPreviewController alloc] init];
677   -// gifPreviewVc.model = model;
678   -// [self.navigationController pushViewController:gifPreviewVc animated:YES];
679   -// }
680   -// } else {
681   -//#pragma mark - 当可以混选
682   -// TZPhotoPreviewController *photoPreviewVc = [[TZPhotoPreviewController alloc] init];
683   -// photoPreviewVc.currentIndex = index;
684   -// photoPreviewVc.models = _models;
685   -// [self pushPhotoPrevireViewController:photoPreviewVc];
686   -// }
687   -}
688   -
689   -#pragma mark - UIScrollViewDelegate
690   -
691   -- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
692   - if (iOS8Later) {
693   - // [self updateCachedAssets];
694   - }
695   -}
696   -
697   -#pragma mark - Private Method
698   -
699   -- (void)setUseCachedImageAndReloadData {
700   - self.useCachedImage = YES;
701   - [self.collectionView reloadData];
702   - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
703   - self.useCachedImage = NO;
704   - });
705   -}
706   -
707   -/// 拍照按钮点击事件
708   -- (void)takePhoto {
709   - AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
710   - if ((authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied) && iOS7Later) {
711   -
712   - NSDictionary *infoDict = [TZCommonTools tz_getInfoDictionary];
713   - // 无权限 做一个友好的提示
714   - NSString *appName = [infoDict valueForKey:@"CFBundleDisplayName"];
715   - if (!appName) appName = [infoDict valueForKey:@"CFBundleName"];
716   -
717   - NSString *message = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Please allow %@ to access your camera in \"Settings -> Privacy -> Camera\""],appName];
718   - if (iOS8Later) {
719   - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSBundle tz_localizedStringForKey:@"Can not use camera"] message:message delegate:self cancelButtonTitle:[NSBundle tz_localizedStringForKey:@"Cancel"] otherButtonTitles:[NSBundle tz_localizedStringForKey:@"Setting"], nil];
720   - [alert show];
721   - } else {
722   - UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSBundle tz_localizedStringForKey:@"Can not use camera"] message:message delegate:self cancelButtonTitle:[NSBundle tz_localizedStringForKey:@"OK"] otherButtonTitles:nil];
723   - [alert show];
724   - }
725   - } else if (authStatus == AVAuthorizationStatusNotDetermined) {
726   - // fix issue 466, 防止用户首次拍照拒绝授权时相机页黑屏
727   - if (iOS7Later) {
728   - [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
729   - if (granted) {
730   - dispatch_async(dispatch_get_main_queue(), ^{
731   - [self pushImagePickerController];
732   - });
733   - }
734   - }];
735   - } else {
736   - [self pushImagePickerController];
737   - }
738   - } else {
739   - [self pushImagePickerController];
740   - }
741   -}
742   -
743   -// 调用相机
744   -- (void)pushImagePickerController {
745   - // 提前定位
746   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
747   - if (tzImagePickerVc.allowCameraLocation) {
748   - __weak typeof(self) weakSelf = self;
749   - [[TZLocationManager manager] startLocationWithSuccessBlock:^(NSArray<CLLocation *> *locations) {
750   - __strong typeof(weakSelf) strongSelf = weakSelf;
751   - strongSelf.location = [locations firstObject];
752   - } failureBlock:^(NSError *error) {
753   - __strong typeof(weakSelf) strongSelf = weakSelf;
754   - strongSelf.location = nil;
755   - }];
756   - }
757   -
758   - UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
759   - if ([UIImagePickerController isSourceTypeAvailable: sourceType]) {
760   - self.imagePickerVc.sourceType = sourceType;
761   - NSMutableArray *mediaTypes = [NSMutableArray array];
762   - if (tzImagePickerVc.allowTakePicture) {
763   - [mediaTypes addObject:(NSString *)kUTTypeImage];
764   - }
765   - if (tzImagePickerVc.allowTakeVideo) {
766   - [mediaTypes addObject:(NSString *)kUTTypeMovie];
767   - self.imagePickerVc.videoMaximumDuration = tzImagePickerVc.videoMaximumDuration;
768   - }
769   - self.imagePickerVc.mediaTypes= mediaTypes;
770   - if (iOS8Later) {
771   - _imagePickerVc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
772   - }
773   - if (tzImagePickerVc.uiImagePickerControllerSettingBlock) {
774   - tzImagePickerVc.uiImagePickerControllerSettingBlock(_imagePickerVc);
775   - }
776   - [self presentViewController:_imagePickerVc animated:YES completion:nil];
777   - } else {
778   - NSLog(@"模拟器中无法打开照相机,请在真机中使用");
779   - }
780   -}
781   -
782   -- (void)refreshBottomToolBarStatus {
783   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
784   -
785   - _previewButton.enabled = tzImagePickerVc.selectedModels.count > 0;
786   - _doneButton.enabled = tzImagePickerVc.selectedModels.count > 0 || tzImagePickerVc.alwaysEnableDoneBtn;
787   -
788   - _numberImageView.hidden = tzImagePickerVc.selectedModels.count <= 0;
789   - _numberLabel.hidden = tzImagePickerVc.selectedModels.count <= 0;
790   - _numberLabel.text = [NSString stringWithFormat:@"%zd",tzImagePickerVc.selectedModels.count];
791   -#pragma mark - ADD: 选择图片个数显示(LXG)
792   - _numberImageView.hidden = YES;
793   - _numberLabel.hidden = YES;
794   - [_doneButton setTitle:[NSString stringWithFormat:@"完成(%zd)",tzImagePickerVc.selectedModels.count] forState:UIControlStateNormal];
795   -
796   - _originalPhotoButton.enabled = tzImagePickerVc.selectedModels.count > 0;
797   - _originalPhotoButton.selected = (_isSelectOriginalPhoto && _originalPhotoButton.enabled);
798   - _originalPhotoLabel.hidden = YES;///lxg添加
799   -// _originalPhotoLabel.hidden = (!_originalPhotoButton.isSelected);///lxg注释
800   - if (_isSelectOriginalPhoto) [self getSelectedPhotoBytes];
801   -}
802   -
803   -- (void)pushPhotoPrevireViewController:(TZPhotoPreviewController *)photoPreviewVc {
804   - [self pushPhotoPrevireViewController:photoPreviewVc needCheckSelectedModels:NO];
805   -}
806   -
807   -- (void)pushPhotoPrevireViewController:(TZPhotoPreviewController *)photoPreviewVc needCheckSelectedModels:(BOOL)needCheckSelectedModels {
808   - __weak typeof(self) weakSelf = self;
809   - photoPreviewVc.isSelectOriginalPhoto = _isSelectOriginalPhoto;
810   - [photoPreviewVc setBackButtonClickBlock:^(BOOL isSelectOriginalPhoto) {
811   - __strong typeof(weakSelf) strongSelf = weakSelf;
812   - strongSelf.isSelectOriginalPhoto = isSelectOriginalPhoto;
813   - if (needCheckSelectedModels) {
814   - [strongSelf checkSelectedModels];
815   - }
816   - [strongSelf.collectionView reloadData];
817   - [strongSelf refreshBottomToolBarStatus];
818   - }];
819   - [photoPreviewVc setDoneButtonClickBlock:^(BOOL isSelectOriginalPhoto) {
820   - __strong typeof(weakSelf) strongSelf = weakSelf;
821   - strongSelf.isSelectOriginalPhoto = isSelectOriginalPhoto;
822   - [strongSelf doneButtonClick];
823   - }];
824   - [photoPreviewVc setDoneButtonClickBlockCropMode:^(UIImage *cropedImage, id asset) {
825   - __strong typeof(weakSelf) strongSelf = weakSelf;
826   - [strongSelf didGetAllPhotos:@[cropedImage] assets:@[asset] infoArr:nil];
827   - }];
828   - [self.navigationController pushViewController:photoPreviewVc animated:YES];
829   -}
830   -
831   -- (void)getSelectedPhotoBytes {
832   - // 越南语 && 5屏幕时会显示不下,暂时这样处理
833   - if ([[TZImagePickerConfig sharedInstance].preferredLanguage isEqualToString:@"vi"] && self.view.tz_width <= 320) {
834   - return;
835   - }
836   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
837   - [[TZImageManager manager] getPhotosBytesWithArray:imagePickerVc.selectedModels completion:^(NSString *totalBytes) {
838   - self->_originalPhotoLabel.text = [NSString stringWithFormat:@"(%@)",totalBytes];
839   - self->_originalPhotoLabel.hidden = YES;///lxg添加
840   - }];
841   -}
842   -
843   -- (void)scrollCollectionViewToBottom {
844   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
845   - if (_shouldScrollToBottom && _models.count > 0) {
846   - NSInteger item = 0;
847   - if (tzImagePickerVc.sortAscendingByModificationDate) {
848   - item = _models.count - 1;
849   - if (_showTakePhotoBtn) {
850   - item += 1;
851   - }
852   - }
853   - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
854   - [self->_collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:item inSection:0] atScrollPosition:UICollectionViewScrollPositionBottom animated:NO];
855   - self->_shouldScrollToBottom = NO;
856   - self->_collectionView.hidden = NO;
857   - });
858   - } else {
859   - _collectionView.hidden = NO;
860   - }
861   -}
862   -
863   -- (void)checkSelectedModels {
864   - NSMutableArray *selectedAssets = [NSMutableArray array];
865   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
866   - for (TZAssetModel *model in tzImagePickerVc.selectedModels) {
867   - [selectedAssets addObject:model.asset];
868   - }
869   - for (TZAssetModel *model in _models) {
870   - model.isSelected = NO;
871   - if ([[TZImageManager manager] isAssetsArray:selectedAssets containAsset:model.asset]) {
872   - model.isSelected = YES;
873   - }
874   - }
875   -}
876   -
877   -#pragma mark - UIAlertViewDelegate
878   -
879   -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
880   - if (buttonIndex == 1) { // 去设置界面,开启相机访问权限
881   - if (iOS8Later) {
882   - [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
883   - }
884   - }
885   -}
886   -
887   -#pragma mark - UIImagePickerControllerDelegate
888   -
889   -- (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
890   - [picker dismissViewControllerAnimated:YES completion:nil];
891   - NSString *type = [info objectForKey:UIImagePickerControllerMediaType];
892   - if ([type isEqualToString:@"public.image"]) {
893   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
894   - [imagePickerVc showProgressHUD];
895   - UIImage *photo = [info objectForKey:UIImagePickerControllerOriginalImage];
896   - if (photo) {
897   - [[TZImageManager manager] savePhotoWithImage:photo location:self.location completion:^(NSError *error){
898   - if (!error) {
899   - [self reloadPhotoArrayWithMediaType:type];
900   - }
901   - }];
902   - self.location = nil;
903   - }
904   - } else if ([type isEqualToString:@"public.movie"]) {
905   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
906   - [imagePickerVc showProgressHUD];
907   - NSURL *videoUrl = [info objectForKey:UIImagePickerControllerMediaURL];
908   - if (videoUrl) {
909   - [[TZImageManager manager] saveVideoWithUrl:videoUrl location:self.location completion:^(NSError *error) {
910   - if (!error) {
911   - [self reloadPhotoArrayWithMediaType:type];
912   - }
913   - }];
914   - self.location = nil;
915   - }
916   - }
917   -}
918   -
919   -- (void)reloadPhotoArrayWithMediaType:(NSString *)mediaType {
920   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
921   - [[TZImageManager manager] getCameraRollAlbum:tzImagePickerVc.allowPickingVideo allowPickingImage:tzImagePickerVc.allowPickingImage needFetchAssets:NO completion:^(TZAlbumModel *model) {
922   - self->_model = model;
923   - [[TZImageManager manager] getAssetsFromFetchResult:self->_model.result completion:^(NSArray<TZAssetModel *> *models) {
924   - [tzImagePickerVc hideProgressHUD];
925   -
926   - TZAssetModel *assetModel;
927   - if (tzImagePickerVc.sortAscendingByModificationDate) {
928   - assetModel = [models lastObject];
929   - [self->_models addObject:assetModel];
930   - } else {
931   - assetModel = [models firstObject];
932   - [self->_models insertObject:assetModel atIndex:0];
933   - }
934   -
935   - if (tzImagePickerVc.maxImagesCount <= 1) {
936   - if (tzImagePickerVc.allowCrop) {
937   - TZPhotoPreviewController *photoPreviewVc = [[TZPhotoPreviewController alloc] init];
938   - if (tzImagePickerVc.sortAscendingByModificationDate) {
939   - photoPreviewVc.currentIndex = self->_models.count - 1;
940   - } else {
941   - photoPreviewVc.currentIndex = 0;
942   - }
943   - photoPreviewVc.models = self->_models;
944   - [self pushPhotoPrevireViewController:photoPreviewVc];
945   - } else {
946   - [tzImagePickerVc addSelectedModel:assetModel];
947   - [self doneButtonClick];
948   - }
949   - return;
950   - }
951   -
952   - if (tzImagePickerVc.selectedModels.count < tzImagePickerVc.maxImagesCount) {
953   - if ([mediaType isEqualToString:@"public.movie"] && !tzImagePickerVc.allowPickingMultipleVideo) {
954   - // 不能多选视频的情况下,不选中拍摄的视频
955   - } else {
956   - assetModel.isSelected = YES;
957   - [tzImagePickerVc addSelectedModel:assetModel];
958   - [self refreshBottomToolBarStatus];
959   - }
960   - }
961   - self->_collectionView.hidden = YES;
962   - [self->_collectionView reloadData];
963   -
964   - self->_shouldScrollToBottom = YES;
965   - [self scrollCollectionViewToBottom];
966   - }];
967   - }];
968   -}
969   -
970   -- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
971   - [picker dismissViewControllerAnimated:YES completion:nil];
972   -}
973   -
974   -- (void)dealloc {
975   - // NSLog(@"%@ dealloc",NSStringFromClass(self.class));
976   -}
977   -
978   -#pragma mark - Asset Caching
979   -
980   -- (void)resetCachedAssets {
981   - [[TZImageManager manager].cachingImageManager stopCachingImagesForAllAssets];
982   - self.previousPreheatRect = CGRectZero;
983   -}
984   -
985   -- (void)updateCachedAssets {
986   - BOOL isViewVisible = [self isViewLoaded] && [[self view] window] != nil;
987   - if (!isViewVisible) { return; }
988   -
989   - // The preheat window is twice the height of the visible rect.
990   - CGRect preheatRect = _collectionView.bounds;
991   - preheatRect = CGRectInset(preheatRect, 0.0f, -0.5f * CGRectGetHeight(preheatRect));
992   -
993   - /*
994   - Check if the collection view is showing an area that is significantly
995   - different to the last preheated area.
996   - */
997   - CGFloat delta = ABS(CGRectGetMidY(preheatRect) - CGRectGetMidY(self.previousPreheatRect));
998   - if (delta > CGRectGetHeight(_collectionView.bounds) / 3.0f) {
999   -
1000   - // Compute the assets to start caching and to stop caching.
1001   - NSMutableArray *addedIndexPaths = [NSMutableArray array];
1002   - NSMutableArray *removedIndexPaths = [NSMutableArray array];
1003   -
1004   - [self computeDifferenceBetweenRect:self.previousPreheatRect andRect:preheatRect removedHandler:^(CGRect removedRect) {
1005   - NSArray *indexPaths = [self aapl_indexPathsForElementsInRect:removedRect];
1006   - [removedIndexPaths addObjectsFromArray:indexPaths];
1007   - } addedHandler:^(CGRect addedRect) {
1008   - NSArray *indexPaths = [self aapl_indexPathsForElementsInRect:addedRect];
1009   - [addedIndexPaths addObjectsFromArray:indexPaths];
1010   - }];
1011   -
1012   - NSArray *assetsToStartCaching = [self assetsAtIndexPaths:addedIndexPaths];
1013   - NSArray *assetsToStopCaching = [self assetsAtIndexPaths:removedIndexPaths];
1014   -
1015   - // Update the assets the PHCachingImageManager is caching.
1016   - [[TZImageManager manager].cachingImageManager startCachingImagesForAssets:assetsToStartCaching
1017   - targetSize:AssetGridThumbnailSize
1018   - contentMode:PHImageContentModeAspectFill
1019   - options:nil];
1020   - [[TZImageManager manager].cachingImageManager stopCachingImagesForAssets:assetsToStopCaching
1021   - targetSize:AssetGridThumbnailSize
1022   - contentMode:PHImageContentModeAspectFill
1023   - options:nil];
1024   -
1025   - // Store the preheat rect to compare against in the future.
1026   - self.previousPreheatRect = preheatRect;
1027   - }
1028   -}
1029   -
1030   -- (void)computeDifferenceBetweenRect:(CGRect)oldRect andRect:(CGRect)newRect removedHandler:(void (^)(CGRect removedRect))removedHandler addedHandler:(void (^)(CGRect addedRect))addedHandler {
1031   - if (CGRectIntersectsRect(newRect, oldRect)) {
1032   - CGFloat oldMaxY = CGRectGetMaxY(oldRect);
1033   - CGFloat oldMinY = CGRectGetMinY(oldRect);
1034   - CGFloat newMaxY = CGRectGetMaxY(newRect);
1035   - CGFloat newMinY = CGRectGetMinY(newRect);
1036   -
1037   - if (newMaxY > oldMaxY) {
1038   - CGRect rectToAdd = CGRectMake(newRect.origin.x, oldMaxY, newRect.size.width, (newMaxY - oldMaxY));
1039   - addedHandler(rectToAdd);
1040   - }
1041   -
1042   - if (oldMinY > newMinY) {
1043   - CGRect rectToAdd = CGRectMake(newRect.origin.x, newMinY, newRect.size.width, (oldMinY - newMinY));
1044   - addedHandler(rectToAdd);
1045   - }
1046   -
1047   - if (newMaxY < oldMaxY) {
1048   - CGRect rectToRemove = CGRectMake(newRect.origin.x, newMaxY, newRect.size.width, (oldMaxY - newMaxY));
1049   - removedHandler(rectToRemove);
1050   - }
1051   -
1052   - if (oldMinY < newMinY) {
1053   - CGRect rectToRemove = CGRectMake(newRect.origin.x, oldMinY, newRect.size.width, (newMinY - oldMinY));
1054   - removedHandler(rectToRemove);
1055   - }
1056   - } else {
1057   - addedHandler(newRect);
1058   - removedHandler(oldRect);
1059   - }
1060   -}
1061   -
1062   -- (NSArray *)assetsAtIndexPaths:(NSArray *)indexPaths {
1063   - if (indexPaths.count == 0) { return nil; }
1064   -
1065   - NSMutableArray *assets = [NSMutableArray arrayWithCapacity:indexPaths.count];
1066   - for (NSIndexPath *indexPath in indexPaths) {
1067   - if (indexPath.item < _models.count) {
1068   - TZAssetModel *model = _models[indexPath.item];
1069   - [assets addObject:model.asset];
1070   - }
1071   - }
1072   -
1073   - return assets;
1074   -}
1075   -
1076   -- (NSArray *)aapl_indexPathsForElementsInRect:(CGRect)rect {
1077   - NSArray *allLayoutAttributes = [_collectionView.collectionViewLayout layoutAttributesForElementsInRect:rect];
1078   - if (allLayoutAttributes.count == 0) { return nil; }
1079   - NSMutableArray *indexPaths = [NSMutableArray arrayWithCapacity:allLayoutAttributes.count];
1080   - for (UICollectionViewLayoutAttributes *layoutAttributes in allLayoutAttributes) {
1081   - NSIndexPath *indexPath = layoutAttributes.indexPath;
1082   - [indexPaths addObject:indexPath];
1083   - }
1084   - return indexPaths;
1085   -}
1086   -#pragma clang diagnostic pop
1087   -
1088   -@end
1089   -
1090   -
1091   -
1092   -@implementation TZCollectionView
1093   -
1094   -- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
1095   - if ([view isKindOfClass:[UIControl class]]) {
1096   - return YES;
1097   - }
1098   - return [super touchesShouldCancelInContentView:view];
1099   -}
1100   -
1101   -@end
CNLiveImagePickerController/TZPhotoPreviewCell.h deleted 100755 → 0
1   -//
2   -// TZPhotoPreviewCell.h
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 15/12/24.
6   -// Copyright © 2015年 谭真. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -@class TZAssetModel;
12   -@interface TZAssetPreviewCell : UICollectionViewCell
13   -@property (nonatomic, strong) TZAssetModel *model;
14   -@property (nonatomic, copy) void (^singleTapGestureBlock)(void);
15   -- (void)configSubviews;
16   -- (void)photoPreviewCollectionViewDidScroll;
17   -@end
18   -
19   -
20   -@class TZAssetModel,TZProgressView,TZPhotoPreviewView;
21   -@interface TZPhotoPreviewCell : TZAssetPreviewCell
22   -
23   -@property (nonatomic, copy) void (^imageProgressUpdateBlock)(double progress);
24   -
25   -@property (nonatomic, strong) TZPhotoPreviewView *previewView;
26   -
27   -@property (nonatomic, assign) BOOL allowCrop;
28   -@property (nonatomic, assign) CGRect cropRect;
29   -
30   -- (void)recoverSubviews;
31   -
32   -@end
33   -
34   -
35   -@interface TZPhotoPreviewView : UIView
36   -@property (nonatomic, strong) UIImageView *imageView;
37   -@property (nonatomic, strong) UIScrollView *scrollView;
38   -@property (nonatomic, strong) UIView *imageContainerView;
39   -@property (nonatomic, strong) TZProgressView *progressView;
40   -
41   -@property (nonatomic, assign) BOOL allowCrop;
42   -@property (nonatomic, assign) CGRect cropRect;
43   -
44   -@property (nonatomic, strong) TZAssetModel *model;
45   -@property (nonatomic, strong) id asset;
46   -@property (nonatomic, copy) void (^singleTapGestureBlock)(void);
47   -@property (nonatomic, copy) void (^imageProgressUpdateBlock)(double progress);
48   -
49   -@property (nonatomic, assign) int32_t imageRequestID;
50   -
51   -- (void)recoverSubviews;
52   -@end
53   -
54   -
55   -@class AVPlayer, AVPlayerLayer;
56   -@interface TZVideoPreviewCell : TZAssetPreviewCell
57   -@property (strong, nonatomic) AVPlayer *player;
58   -@property (strong, nonatomic) AVPlayerLayer *playerLayer;
59   -@property (strong, nonatomic) UIButton *playButton;
60   -@property (strong, nonatomic) UIImage *cover;
61   -- (void)pausePlayerAndShowNaviBar;
62   -@end
63   -
64   -
65   -@interface TZGifPreviewCell : TZAssetPreviewCell
66   -@property (strong, nonatomic) TZPhotoPreviewView *previewView;
67   -@end
CNLiveImagePickerController/TZPhotoPreviewCell.m deleted 100755 → 0
1   -//
2   -// TZPhotoPreviewCell.m
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 15/12/24.
6   -// Copyright © 2015年 谭真. All rights reserved.
7   -//
8   -
9   -#import "TZPhotoPreviewCell.h"
10   -#import "TZAssetModel.h"
11   -#import "UIView+Layout.h"
12   -#import "TZImageManager.h"
13   -#import "TZProgressView.h"
14   -#import "TZImageCropManager.h"
15   -#import <MediaPlayer/MediaPlayer.h>
16   -#import "TZImagePickerController.h"
17   -
18   -@implementation TZAssetPreviewCell
19   -
20   -- (instancetype)initWithFrame:(CGRect)frame {
21   - self = [super initWithFrame:frame];
22   - if (self) {
23   - self.backgroundColor = [UIColor blackColor];
24   - [self configSubviews];
25   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(photoPreviewCollectionViewDidScroll) name:@"photoPreviewCollectionViewDidScroll" object:nil];
26   - }
27   - return self;
28   -}
29   -
30   -- (void)configSubviews {
31   -
32   -}
33   -
34   -#pragma mark - Notification
35   -
36   -- (void)photoPreviewCollectionViewDidScroll {
37   -
38   -}
39   -
40   -- (void)dealloc {
41   - [[NSNotificationCenter defaultCenter] removeObserver:self];
42   -}
43   -
44   -@end
45   -
46   -
47   -@implementation TZPhotoPreviewCell
48   -
49   -- (void)configSubviews {
50   - self.previewView = [[TZPhotoPreviewView alloc] initWithFrame:CGRectZero];
51   - __weak typeof(self) weakSelf = self;
52   - [self.previewView setSingleTapGestureBlock:^{
53   - __strong typeof(weakSelf) strongSelf = weakSelf;
54   - if (strongSelf.singleTapGestureBlock) {
55   - strongSelf.singleTapGestureBlock();
56   - }
57   - }];
58   - [self.previewView setImageProgressUpdateBlock:^(double progress) {
59   - __strong typeof(weakSelf) strongSelf = weakSelf;
60   - if (strongSelf.imageProgressUpdateBlock) {
61   - strongSelf.imageProgressUpdateBlock(progress);
62   - }
63   - }];
64   - [self addSubview:self.previewView];
65   -}
66   -
67   -- (void)setModel:(TZAssetModel *)model {
68   - [super setModel:model];
69   - _previewView.asset = model.asset;
70   -}
71   -
72   -- (void)recoverSubviews {
73   - [_previewView recoverSubviews];
74   -}
75   -
76   -- (void)setAllowCrop:(BOOL)allowCrop {
77   - _allowCrop = allowCrop;
78   - _previewView.allowCrop = allowCrop;
79   -}
80   -
81   -- (void)setCropRect:(CGRect)cropRect {
82   - _cropRect = cropRect;
83   - _previewView.cropRect = cropRect;
84   -}
85   -
86   -- (void)layoutSubviews {
87   - [super layoutSubviews];
88   - self.previewView.frame = self.bounds;
89   -}
90   -
91   -@end
92   -
93   -
94   -@interface TZPhotoPreviewView ()<UIScrollViewDelegate>
95   -@property (assign, nonatomic) BOOL isRequestingGIF;
96   -@end
97   -
98   -@implementation TZPhotoPreviewView
99   -
100   -- (instancetype)initWithFrame:(CGRect)frame {
101   - self = [super initWithFrame:frame];
102   - if (self) {
103   - _scrollView = [[UIScrollView alloc] init];
104   - _scrollView.bouncesZoom = YES;
105   - _scrollView.maximumZoomScale = 2.5;
106   - _scrollView.minimumZoomScale = 1.0;
107   - _scrollView.multipleTouchEnabled = YES;
108   - _scrollView.delegate = self;
109   - _scrollView.scrollsToTop = NO;
110   - _scrollView.showsHorizontalScrollIndicator = NO;
111   - _scrollView.showsVerticalScrollIndicator = YES;
112   - _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
113   - _scrollView.delaysContentTouches = NO;
114   - _scrollView.canCancelContentTouches = YES;
115   - _scrollView.alwaysBounceVertical = NO;
116   - if (@available(iOS 11, *)) {
117   - _scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
118   - }
119   - [self addSubview:_scrollView];
120   -
121   - _imageContainerView = [[UIView alloc] init];
122   - _imageContainerView.clipsToBounds = YES;
123   - _imageContainerView.contentMode = UIViewContentModeScaleAspectFill;
124   - [_scrollView addSubview:_imageContainerView];
125   -
126   - _imageView = [[UIImageView alloc] init];
127   - _imageView.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.500];
128   - _imageView.contentMode = UIViewContentModeScaleAspectFill;
129   - _imageView.clipsToBounds = YES;
130   - [_imageContainerView addSubview:_imageView];
131   -
132   - UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
133   - [self addGestureRecognizer:tap1];
134   - UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap:)];
135   - tap2.numberOfTapsRequired = 2;
136   - [tap1 requireGestureRecognizerToFail:tap2];
137   - [self addGestureRecognizer:tap2];
138   -
139   - [self configProgressView];
140   - }
141   - return self;
142   -}
143   -
144   -- (void)configProgressView {
145   - _progressView = [[TZProgressView alloc] init];
146   - _progressView.hidden = YES;
147   - [self addSubview:_progressView];
148   -}
149   -
150   -- (void)setModel:(TZAssetModel *)model {
151   - _model = model;
152   - self.isRequestingGIF = NO;
153   - [_scrollView setZoomScale:1.0 animated:NO];
154   - if (model.type == TZAssetModelMediaTypePhotoGif) {
155   - // 先显示缩略图
156   - [[TZImageManager manager] getPhotoWithAsset:model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
157   - self.imageView.image = photo;
158   - [self resizeSubviews];
159   - if (self.isRequestingGIF) {
160   - return;
161   - }
162   - // 再显示gif动图
163   - self.isRequestingGIF = YES;
164   - [[TZImageManager manager] getOriginalPhotoDataWithAsset:model.asset progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
165   - progress = progress > 0.02 ? progress : 0.02;
166   - dispatch_async(dispatch_get_main_queue(), ^{
167   - self.progressView.progress = progress;
168   - if (progress >= 1) {
169   - self.progressView.hidden = YES;
170   - } else {
171   - self.progressView.hidden = NO;
172   - }
173   - });
174   -#ifdef DEBUG
175   - NSLog(@"[TZImagePickerController] getOriginalPhotoDataWithAsset:%f error:%@", progress, error);
176   -#endif
177   - } completion:^(NSData *data, NSDictionary *info, BOOL isDegraded) {
178   - if (!isDegraded) {
179   - self.isRequestingGIF = NO;
180   - self.progressView.hidden = YES;
181   - self.imageView.image = [UIImage sd_tz_animatedGIFWithData:data];
182   - [self resizeSubviews];
183   - }
184   - }];
185   - } progressHandler:nil networkAccessAllowed:NO];
186   - } else {
187   - self.asset = model.asset;
188   - }
189   -}
190   -
191   -- (void)setAsset:(id)asset {
192   - if (_asset && self.imageRequestID) {
193   - [[PHImageManager defaultManager] cancelImageRequest:self.imageRequestID];
194   - }
195   -
196   - _asset = asset;
197   - self.imageRequestID = [[TZImageManager manager] getPhotoWithAsset:asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
198   - if (![asset isEqual:self->_asset]) return;
199   - self.imageView.image = photo;
200   - [self resizeSubviews];
201   - self->_progressView.hidden = YES;
202   - if (self.imageProgressUpdateBlock) {
203   - self.imageProgressUpdateBlock(1);
204   - }
205   - if (!isDegraded) {
206   - self.imageRequestID = 0;
207   - }
208   - } progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
209   - if (![asset isEqual:self->_asset]) return;
210   - self->_progressView.hidden = NO;
211   - [self bringSubviewToFront:self->_progressView];
212   - progress = progress > 0.02 ? progress : 0.02;
213   - self->_progressView.progress = progress;
214   - if (self.imageProgressUpdateBlock && progress < 1) {
215   - self.imageProgressUpdateBlock(progress);
216   - }
217   -
218   - if (progress >= 1) {
219   - self->_progressView.hidden = YES;
220   - self.imageRequestID = 0;
221   - }
222   - } networkAccessAllowed:YES];
223   -}
224   -
225   -- (void)recoverSubviews {
226   - [_scrollView setZoomScale:1.0 animated:NO];
227   - [self resizeSubviews];
228   -}
229   -
230   -- (void)resizeSubviews {
231   - _imageContainerView.tz_origin = CGPointZero;
232   - _imageContainerView.tz_width = self.scrollView.tz_width;
233   -
234   - UIImage *image = _imageView.image;
235   - if (image.size.height / image.size.width > self.tz_height / self.scrollView.tz_width) {
236   - _imageContainerView.tz_height = floor(image.size.height / (image.size.width / self.scrollView.tz_width));
237   - } else {
238   - CGFloat height = image.size.height / image.size.width * self.scrollView.tz_width;
239   - if (height < 1 || isnan(height)) height = self.tz_height;
240   - height = floor(height);
241   - _imageContainerView.tz_height = height;
242   - _imageContainerView.tz_centerY = self.tz_height / 2;
243   - }
244   - if (_imageContainerView.tz_height > self.tz_height && _imageContainerView.tz_height - self.tz_height <= 1) {
245   - _imageContainerView.tz_height = self.tz_height;
246   - }
247   - CGFloat contentSizeH = MAX(_imageContainerView.tz_height, self.tz_height);
248   - _scrollView.contentSize = CGSizeMake(self.scrollView.tz_width, contentSizeH);
249   - [_scrollView scrollRectToVisible:self.bounds animated:NO];
250   - _scrollView.alwaysBounceVertical = _imageContainerView.tz_height <= self.tz_height ? NO : YES;
251   - _imageView.frame = _imageContainerView.bounds;
252   -
253   - [self refreshScrollViewContentSize];
254   -}
255   -
256   -- (void)setAllowCrop:(BOOL)allowCrop {
257   - _allowCrop = allowCrop;
258   - _scrollView.maximumZoomScale = allowCrop ? 4.0 : 2.5;
259   -
260   - if ([self.asset isKindOfClass:[PHAsset class]]) {
261   - PHAsset *phAsset = (PHAsset *)self.asset;
262   - CGFloat aspectRatio = phAsset.pixelWidth / (CGFloat)phAsset.pixelHeight;
263   - // 优化超宽图片的显示
264   - if (aspectRatio > 1.5) {
265   - self.scrollView.maximumZoomScale *= aspectRatio / 1.5;
266   - }
267   - }
268   -}
269   -
270   -- (void)refreshScrollViewContentSize {
271   - if (_allowCrop) {
272   - // 1.7.2 如果允许裁剪,需要让图片的任意部分都能在裁剪框内,于是对_scrollView做了如下处理:
273   - // 1.让contentSize增大(裁剪框右下角的图片部分)
274   - CGFloat contentWidthAdd = self.scrollView.tz_width - CGRectGetMaxX(_cropRect);
275   - CGFloat contentHeightAdd = (MIN(_imageContainerView.tz_height, self.tz_height) - self.cropRect.size.height) / 2;
276   - CGFloat newSizeW = self.scrollView.contentSize.width + contentWidthAdd;
277   - CGFloat newSizeH = MAX(self.scrollView.contentSize.height, self.tz_height) + contentHeightAdd;
278   - _scrollView.contentSize = CGSizeMake(newSizeW, newSizeH);
279   - _scrollView.alwaysBounceVertical = YES;
280   - // 2.让scrollView新增滑动区域(裁剪框左上角的图片部分)
281   - if (contentHeightAdd > 0 || contentWidthAdd > 0) {
282   - _scrollView.contentInset = UIEdgeInsetsMake(contentHeightAdd, _cropRect.origin.x, 0, 0);
283   - } else {
284   - _scrollView.contentInset = UIEdgeInsetsZero;
285   - }
286   - }
287   -}
288   -
289   -- (void)layoutSubviews {
290   - [super layoutSubviews];
291   - _scrollView.frame = CGRectMake(10, 0, self.tz_width - 20, self.tz_height);
292   - static CGFloat progressWH = 40;
293   - CGFloat progressX = (self.tz_width - progressWH) / 2;
294   - CGFloat progressY = (self.tz_height - progressWH) / 2;
295   - _progressView.frame = CGRectMake(progressX, progressY, progressWH, progressWH);
296   -
297   - [self recoverSubviews];
298   -}
299   -
300   -#pragma mark - UITapGestureRecognizer Event
301   -
302   -- (void)doubleTap:(UITapGestureRecognizer *)tap {
303   - if (_scrollView.zoomScale > 1.0) {
304   - _scrollView.contentInset = UIEdgeInsetsZero;
305   - [_scrollView setZoomScale:1.0 animated:YES];
306   - } else {
307   - CGPoint touchPoint = [tap locationInView:self.imageView];
308   - CGFloat newZoomScale = _scrollView.maximumZoomScale;
309   - CGFloat xsize = self.frame.size.width / newZoomScale;
310   - CGFloat ysize = self.frame.size.height / newZoomScale;
311   - [_scrollView zoomToRect:CGRectMake(touchPoint.x - xsize/2, touchPoint.y - ysize/2, xsize, ysize) animated:YES];
312   - }
313   -}
314   -
315   -- (void)singleTap:(UITapGestureRecognizer *)tap {
316   - if (self.singleTapGestureBlock) {
317   - self.singleTapGestureBlock();
318   - }
319   -}
320   -
321   -#pragma mark - UIScrollViewDelegate
322   -
323   -- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
324   - return _imageContainerView;
325   -}
326   -
327   -- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {
328   - scrollView.contentInset = UIEdgeInsetsZero;
329   -}
330   -
331   -- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
332   - [self refreshImageContainerViewCenter];
333   -}
334   -
335   -- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
336   - [self refreshScrollViewContentSize];
337   -}
338   -
339   -#pragma mark - Private
340   -
341   -- (void)refreshImageContainerViewCenter {
342   - CGFloat offsetX = (_scrollView.tz_width > _scrollView.contentSize.width) ? ((_scrollView.tz_width - _scrollView.contentSize.width) * 0.5) : 0.0;
343   - CGFloat offsetY = (_scrollView.tz_height > _scrollView.contentSize.height) ? ((_scrollView.tz_height - _scrollView.contentSize.height) * 0.5) : 0.0;
344   - self.imageContainerView.center = CGPointMake(_scrollView.contentSize.width * 0.5 + offsetX, _scrollView.contentSize.height * 0.5 + offsetY);
345   -}
346   -
347   -@end
348   -
349   -
350   -@implementation TZVideoPreviewCell
351   -
352   -- (void)configSubviews {
353   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pausePlayerAndShowNaviBar) name:UIApplicationWillResignActiveNotification object:nil];
354   -}
355   -
356   -- (void)configPlayButton {
357   - if (_playButton) {
358   - [_playButton removeFromSuperview];
359   - }
360   - _playButton = [UIButton buttonWithType:UIButtonTypeCustom];
361   - [_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
362   - [_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlayHL"] forState:UIControlStateHighlighted];
363   - [_playButton addTarget:self action:@selector(playButtonClick) forControlEvents:UIControlEventTouchUpInside];
364   - [self addSubview:_playButton];
365   -}
366   -
367   -- (void)setModel:(TZAssetModel *)model {
368   - [super setModel:model];
369   - [self configMoviePlayer];
370   -}
371   -
372   -- (void)configMoviePlayer {
373   - if (_player) {
374   - [_playerLayer removeFromSuperlayer];
375   - _playerLayer = nil;
376   - [_player pause];
377   - _player = nil;
378   - }
379   -
380   - [[TZImageManager manager] getPhotoWithAsset:self.model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
381   - self->_cover = photo;
382   - }];
383   - [[TZImageManager manager] getVideoWithAsset:self.model.asset completion:^(AVPlayerItem *playerItem, NSDictionary *info) {
384   - dispatch_async(dispatch_get_main_queue(), ^{
385   - self->_player = [AVPlayer playerWithPlayerItem:playerItem];
386   - self->_playerLayer = [AVPlayerLayer playerLayerWithPlayer:self->_player];
387   - self->_playerLayer.backgroundColor = [UIColor blackColor].CGColor;
388   - self->_playerLayer.frame = self.bounds;
389   - [self.layer addSublayer:self->_playerLayer];
390   - [self configPlayButton];
391   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pausePlayerAndShowNaviBar) name:AVPlayerItemDidPlayToEndTimeNotification object:self->_player.currentItem];
392   - });
393   - }];
394   -}
395   -
396   -- (void)layoutSubviews {
397   - [super layoutSubviews];
398   - _playerLayer.frame = self.bounds;
399   - _playButton.frame = CGRectMake(0, 64, self.tz_width, self.tz_height - 64 - 44);
400   -}
401   -
402   -- (void)photoPreviewCollectionViewDidScroll {
403   - [self pausePlayerAndShowNaviBar];
404   -}
405   -
406   -#pragma mark - Click Event
407   -
408   -- (void)playButtonClick {
409   - CMTime currentTime = _player.currentItem.currentTime;
410   - CMTime durationTime = _player.currentItem.duration;
411   - if (_player.rate == 0.0f) {
412   - if (currentTime.value == durationTime.value) [_player.currentItem seekToTime:CMTimeMake(0, 1)];
413   - [_player play];
414   - [_playButton setImage:nil forState:UIControlStateNormal];
415   - if (iOS7Later) [UIApplication sharedApplication].statusBarHidden = YES;
416   - if (self.singleTapGestureBlock) {
417   - self.singleTapGestureBlock();
418   - }
419   - } else {
420   - [self pausePlayerAndShowNaviBar];
421   - }
422   -}
423   -
424   -- (void)pausePlayerAndShowNaviBar {
425   - if (_player.rate != 0.0) {
426   - [_player pause];
427   - [_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
428   - if (self.singleTapGestureBlock) {
429   - self.singleTapGestureBlock();
430   - }
431   - }
432   -}
433   -
434   -@end
435   -
436   -
437   -@implementation TZGifPreviewCell
438   -
439   -- (void)configSubviews {
440   - [self configPreviewView];
441   -}
442   -
443   -- (void)configPreviewView {
444   - _previewView = [[TZPhotoPreviewView alloc] initWithFrame:CGRectZero];
445   - __weak typeof(self) weakSelf = self;
446   - [_previewView setSingleTapGestureBlock:^{
447   - __strong typeof(weakSelf) strongSelf = weakSelf;
448   - [strongSelf signleTapAction];
449   - }];
450   - [self addSubview:_previewView];
451   -}
452   -
453   -- (void)setModel:(TZAssetModel *)model {
454   - [super setModel:model];
455   - _previewView.model = self.model;
456   -}
457   -
458   -- (void)layoutSubviews {
459   - [super layoutSubviews];
460   - _previewView.frame = self.bounds;
461   -}
462   -
463   -#pragma mark - Click Event
464   -
465   -- (void)signleTapAction {
466   - if (self.singleTapGestureBlock) {
467   - self.singleTapGestureBlock();
468   - }
469   -}
470   -
471   -@end
CNLiveImagePickerController/TZPhotoPreviewController.h deleted 100755 → 0
1   -//
2   -// TZPhotoPreviewController.h
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 15/12/24.
6   -// Copyright © 2015年 谭真. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -@interface TZPhotoPreviewController : UIViewController
12   -
13   -@property (nonatomic, strong) NSMutableArray *models; ///< All photo models / 所有图片模型数组
14   -@property (nonatomic, strong) NSMutableArray *photos; ///< All photos / 所有图片数组
15   -@property (nonatomic, assign) NSInteger currentIndex; ///< Index of the photo user click / 用户点击的图片的索引
16   -@property (nonatomic, assign) BOOL isSelectOriginalPhoto; ///< If YES,return original photo / 是否返回原图
17   -@property (nonatomic, assign) BOOL isCropImage;
18   -
19   -/// Return the new selected photos / 返回最新的选中图片数组
20   -@property (nonatomic, copy) void (^backButtonClickBlock)(BOOL isSelectOriginalPhoto);
21   -@property (nonatomic, copy) void (^doneButtonClickBlock)(BOOL isSelectOriginalPhoto);
22   -@property (nonatomic, copy) void (^doneButtonClickBlockCropMode)(UIImage *cropedImage,id asset);
23   -@property (nonatomic, copy) void (^doneButtonClickBlockWithPreviewType)(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto);
24   -
25   -@end
CNLiveImagePickerController/TZPhotoPreviewController.m deleted 100755 → 0
1   -//
2   -// TZPhotoPreviewController.m
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 15/12/24.
6   -// Copyright © 2015年 谭真. All rights reserved.
7   -//
8   -
9   -#import "TZPhotoPreviewController.h"
10   -#import "TZPhotoPreviewCell.h"
11   -#import "TZAssetModel.h"
12   -#import "UIView+Layout.h"
13   -#import "TZImagePickerController.h"
14   -#import "TZImageManager.h"
15   -#import "TZImageCropManager.h"
16   -#import <AssetsLibrary/AssetsLibrary.h>///lxg
17   -#import "CNEditVideoController.h"
18   -
19   -@interface TZPhotoPreviewController ()<UICollectionViewDataSource,UICollectionViewDelegate,UIScrollViewDelegate> {
20   - UICollectionView *_collectionView;
21   - UICollectionViewFlowLayout *_layout;
22   - NSArray *_photosTemp;
23   - NSArray *_assetsTemp;
24   -
25   - UIView *_naviBar;
26   - UIButton *_backButton;
27   - UIButton *_selectButton;
28   - UILabel *_indexLabel;
29   - UIView *_navBarLine;///LXG线
30   -
31   - UIView *_tipBar;///LXG添加提示视图
32   - UILabel *_tipContentLabel;///LXG添加提示内容
33   -
34   -
35   - UIView *_toolBar;
36   - UIButton *_doneButton;
37   - UIImageView *_numberImageView;
38   - UILabel *_numberLabel;
39   - UIButton *_originalPhotoButton;
40   - UILabel *_originalPhotoLabel;
41   - UILabel *_editTipLable;//LXG底部提示
42   - UIButton *_editTipButton;//LXG编辑按钮
43   -
44   -
45   - CGFloat _offsetItemCount;
46   -
47   - BOOL _didSetIsSelectOriginalPhoto;
48   -}
49   -@property (nonatomic, assign) BOOL isHideNaviBar;
50   -@property (nonatomic, strong) UIView *cropBgView;
51   -@property (nonatomic, strong) UIView *cropView;
52   -
53   -@property (nonatomic, assign) double progress;
54   -@property (strong, nonatomic) id alertView;
55   -@end
56   -
57   -@implementation TZPhotoPreviewController
58   -
59   -- (void)viewDidLoad {
60   - [super viewDidLoad];
61   - [TZImageManager manager].shouldFixOrientation = YES;
62   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
63   - if (!_didSetIsSelectOriginalPhoto) {
64   - _isSelectOriginalPhoto = _tzImagePickerVc.isSelectOriginalPhoto;
65   - }
66   - if (!self.models.count) {
67   - self.models = [NSMutableArray arrayWithArray:_tzImagePickerVc.selectedModels];
68   - _assetsTemp = [NSMutableArray arrayWithArray:_tzImagePickerVc.selectedAssets];
69   - }
70   - [self configCollectionView];
71   - [self configCustomNaviBar];
72   - [self configCustomTipBar];///lxg 添加提示
73   - [self configBottomToolBar];
74   - self.view.clipsToBounds = YES;
75   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeStatusBarOrientationNotification:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
76   -}
77   -
78   -- (void)setIsSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto {
79   - _isSelectOriginalPhoto = isSelectOriginalPhoto;
80   - _didSetIsSelectOriginalPhoto = YES;
81   -}
82   -
83   -- (void)setPhotos:(NSMutableArray *)photos {
84   - _photos = photos;
85   - _photosTemp = [NSArray arrayWithArray:photos];
86   -}
87   -
88   -- (void)viewWillAppear:(BOOL)animated {
89   - [super viewWillAppear:animated];
90   - [self.navigationController setNavigationBarHidden:YES animated:YES];
91   - if (iOS7Later) [UIApplication sharedApplication].statusBarHidden = YES;
92   - if (_currentIndex) [_collectionView setContentOffset:CGPointMake((self.view.tz_width + 20) * _currentIndex, 0) animated:NO];
93   - [self refreshNaviBarAndBottomBarState];
94   -}
95   -
96   -- (void)viewWillDisappear:(BOOL)animated {
97   - [super viewWillDisappear:animated];
98   - [self.navigationController setNavigationBarHidden:NO animated:YES];
99   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
100   - if (tzImagePickerVc.needShowStatusBar && iOS7Later) {
101   - [UIApplication sharedApplication].statusBarHidden = NO;
102   - }
103   - [TZImageManager manager].shouldFixOrientation = NO;
104   -}
105   -
106   -- (BOOL)prefersStatusBarHidden {
107   - return YES;
108   -}
109   -
110   -- (void)configCustomNaviBar {
111   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
112   -
113   - _naviBar = [[UIView alloc] initWithFrame:CGRectZero];
114   - _naviBar.backgroundColor = [UIColor colorWithRed:(34/255.0) green:(34/255.0) blue:(34/255.0) alpha:0.7];
115   -
116   - _backButton = [[UIButton alloc] initWithFrame:CGRectZero];
117   - [_backButton setImage:[UIImage imageNamedFromMyBundle:@"navi_back"] forState:UIControlStateNormal];
118   - [_backButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
119   - [_backButton addTarget:self action:@selector(backButtonClick) forControlEvents:UIControlEventTouchUpInside];
120   -
121   - _selectButton = [[UIButton alloc] initWithFrame:CGRectZero];
122   - [_selectButton setImage:tzImagePickerVc.photoDefImage forState:UIControlStateNormal];
123   - [_selectButton setImage:tzImagePickerVc.photoSelImage forState:UIControlStateSelected];
124   - _selectButton.imageView.clipsToBounds = YES;
125   - _selectButton.imageEdgeInsets = UIEdgeInsetsMake(10, 0, 10, 0);
126   - _selectButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
127   - [_selectButton addTarget:self action:@selector(select:) forControlEvents:UIControlEventTouchUpInside];
128   - _selectButton.hidden = !tzImagePickerVc.showSelectBtn;
129   -
130   - _indexLabel = [[UILabel alloc] init];
131   - _indexLabel.font = [UIFont systemFontOfSize:14];
132   - _indexLabel.textColor = [UIColor whiteColor];
133   - _indexLabel.textAlignment = NSTextAlignmentCenter;
134   - ///lxg 导航栏线
135   - _navBarLine = [[UIView alloc]init];
136   - _navBarLine.backgroundColor = [UIColor colorWithWhite:0.5 alpha:1];
137   - _navBarLine.hidden = YES;
138   -
139   - [_naviBar addSubview:_selectButton];
140   - [_naviBar addSubview:_indexLabel];
141   - [_naviBar addSubview:_backButton];
142   - [_naviBar addSubview:_navBarLine];///lxg 添加线
143   - [self.view addSubview:_naviBar];
144   -}
145   -
146   -/// 添加提示条(LXG)
147   -- (void)configCustomTipBar {
148   - _tipBar = [[UIView alloc] initWithFrame:CGRectZero];
149   - static CGFloat rgb = 34 / 255.0;
150   - _tipBar.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:0.7];
151   - _tipBar.hidden = YES;
152   -
153   - _tipContentLabel = [[UILabel alloc] init];
154   - _tipContentLabel.font = [UIFont systemFontOfSize:15];
155   - _tipContentLabel.textColor = [UIColor whiteColor];
156   - _tipContentLabel.textAlignment = NSTextAlignmentLeft;
157   - _tipContentLabel.backgroundColor = [UIColor clearColor];
158   -
159   - [_tipBar addSubview:_tipContentLabel];
160   - [self.view addSubview:_tipBar];
161   -
162   -
163   -}
164   -
165   -- (void)configBottomToolBar {
166   - _toolBar = [[UIView alloc] initWithFrame:CGRectZero];
167   - static CGFloat rgb = 34 / 255.0;
168   - _toolBar.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:0.7];
169   -
170   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
171   - if (_tzImagePickerVc.allowPickingOriginalPhoto) {
172   - _originalPhotoButton = [UIButton buttonWithType:UIButtonTypeCustom];
173   - _originalPhotoButton.imageEdgeInsets = UIEdgeInsetsMake(0, -10, 0, 0);
174   - _originalPhotoButton.backgroundColor = [UIColor clearColor];
175   - [_originalPhotoButton addTarget:self action:@selector(originalPhotoButtonClick) forControlEvents:UIControlEventTouchUpInside];
176   - _originalPhotoButton.titleLabel.font = [UIFont systemFontOfSize:13];
177   - [_originalPhotoButton setTitle:_tzImagePickerVc.fullImageBtnTitleStr forState:UIControlStateNormal];
178   - [_originalPhotoButton setTitle:_tzImagePickerVc.fullImageBtnTitleStr forState:UIControlStateSelected];
179   - [_originalPhotoButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
180   - [_originalPhotoButton setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
181   - [_originalPhotoButton setImage:_tzImagePickerVc.photoPreviewOriginDefImage forState:UIControlStateNormal];
182   - [_originalPhotoButton setImage:_tzImagePickerVc.photoOriginSelImage forState:UIControlStateSelected];
183   -
184   - _originalPhotoLabel = [[UILabel alloc] init];
185   - _originalPhotoLabel.textAlignment = NSTextAlignmentLeft;
186   - _originalPhotoLabel.font = [UIFont systemFontOfSize:13];
187   - _originalPhotoLabel.textColor = [UIColor whiteColor];
188   - _originalPhotoLabel.backgroundColor = [UIColor clearColor];
189   - if (_isSelectOriginalPhoto) [self showPhotoBytes];
190   - }
191   -
192   - _doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
193   - _doneButton.titleLabel.font = [UIFont systemFontOfSize:16];
194   - [_doneButton addTarget:self action:@selector(doneButtonClick) forControlEvents:UIControlEventTouchUpInside];
195   - [_doneButton setTitle:_tzImagePickerVc.doneBtnTitleStr forState:UIControlStateNormal];
196   - [_doneButton setTitleColor:_tzImagePickerVc.oKButtonTitleColorNormal forState:UIControlStateNormal];
197   -
198   - _numberImageView = [[UIImageView alloc] initWithImage:_tzImagePickerVc.photoNumberIconImage];
199   - _numberImageView.backgroundColor = [UIColor clearColor];
200   - _numberImageView.clipsToBounds = YES;
201   - _numberImageView.contentMode = UIViewContentModeScaleAspectFit;
202   - _numberImageView.hidden = _tzImagePickerVc.selectedModels.count <= 0;
203   -
204   - _numberLabel = [[UILabel alloc] init];
205   - _numberLabel.font = [UIFont systemFontOfSize:15];
206   - _numberLabel.textColor = [UIColor whiteColor];
207   - _numberLabel.textAlignment = NSTextAlignmentCenter;
208   - _numberLabel.text = [NSString stringWithFormat:@"%zd",_tzImagePickerVc.selectedModels.count];
209   - _numberLabel.hidden = _tzImagePickerVc.selectedModels.count <= 0;
210   - _numberLabel.backgroundColor = [UIColor clearColor];
211   -#pragma mark - ADD: 选择图片个数显示(LXG)
212   - _numberImageView.hidden = YES;
213   - _numberLabel.hidden = YES;
214   - NSString *titleStr = _tzImagePickerVc.selectedModels.count > 0 ? [NSString stringWithFormat:@"完成(%zd)",_tzImagePickerVc.selectedModels.count] : @"完成";
215   - [_doneButton setTitle:titleStr forState:UIControlStateNormal];
216   -
217   - ///LXG 添加视频编辑
218   - _editTipLable = [[UILabel alloc] init];
219   - _editTipLable.font = [UIFont systemFontOfSize:15];
220   - _editTipLable.textAlignment = NSTextAlignmentLeft;
221   - _editTipLable.hidden = YES;
222   - _editTipLable.textColor = [UIColor whiteColor];
223   - _editTipLable.backgroundColor = [UIColor clearColor];
224   - _editTipButton = [UIButton buttonWithType:UIButtonTypeCustom];
225   - _editTipButton.titleLabel.font = [UIFont systemFontOfSize:16];
226   - [_editTipButton addTarget:self action:@selector(editVideoButtonClick) forControlEvents:UIControlEventTouchUpInside];
227   - _editTipButton.hidden = YES;
228   - [_editTipButton setTitle:_tzImagePickerVc.editBtnTitleStr forState:UIControlStateNormal];
229   - [_editTipButton setTitleColor:_tzImagePickerVc.editBtnTitleColor forState:UIControlStateNormal];
230   -
231   - [_originalPhotoButton addSubview:_originalPhotoLabel];
232   - [_toolBar addSubview:_doneButton];
233   - [_toolBar addSubview:_originalPhotoButton];
234   - [_toolBar addSubview:_numberImageView];
235   - [_toolBar addSubview:_numberLabel];
236   - [_toolBar addSubview:_editTipLable];///LXG
237   - [_toolBar addSubview:_editTipButton];///LXG
238   - [self.view addSubview:_toolBar];
239   -
240   - if (_tzImagePickerVc.photoPreviewPageUIConfigBlock) {
241   - _tzImagePickerVc.photoPreviewPageUIConfigBlock(_collectionView, _naviBar, _backButton, _selectButton, _indexLabel, _toolBar, _originalPhotoButton, _originalPhotoLabel, _doneButton, _numberImageView, _numberLabel);
242   - }
243   -}
244   -
245   -- (void)configCollectionView {
246   - _layout = [[UICollectionViewFlowLayout alloc] init];
247   - _layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
248   - _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:_layout];
249   - _collectionView.backgroundColor = [UIColor blackColor];
250   - _collectionView.dataSource = self;
251   - _collectionView.delegate = self;
252   - _collectionView.pagingEnabled = YES;
253   - _collectionView.scrollsToTop = NO;
254   - _collectionView.showsHorizontalScrollIndicator = NO;
255   - _collectionView.contentOffset = CGPointMake(0, 0);
256   - _collectionView.contentSize = CGSizeMake(self.models.count * (self.view.tz_width + 20), 0);
257   - [self.view addSubview:_collectionView];
258   - [_collectionView registerClass:[TZPhotoPreviewCell class] forCellWithReuseIdentifier:@"TZPhotoPreviewCell"];
259   - [_collectionView registerClass:[TZVideoPreviewCell class] forCellWithReuseIdentifier:@"TZVideoPreviewCell"];
260   - [_collectionView registerClass:[TZGifPreviewCell class] forCellWithReuseIdentifier:@"TZGifPreviewCell"];
261   -}
262   -
263   -- (void)configCropView {
264   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
265   - if (_tzImagePickerVc.maxImagesCount <= 1 && _tzImagePickerVc.allowCrop) {
266   - [_cropView removeFromSuperview];
267   - [_cropBgView removeFromSuperview];
268   -
269   - _cropBgView = [UIView new];
270   - _cropBgView.userInteractionEnabled = NO;
271   - _cropBgView.frame = self.view.bounds;
272   - _cropBgView.backgroundColor = [UIColor clearColor];
273   - [self.view addSubview:_cropBgView];
274   - [TZImageCropManager overlayClippingWithView:_cropBgView cropRect:_tzImagePickerVc.cropRect containerView:self.view needCircleCrop:_tzImagePickerVc.needCircleCrop];
275   -
276   - _cropView = [UIView new];
277   - _cropView.userInteractionEnabled = NO;
278   - _cropView.frame = _tzImagePickerVc.cropRect;
279   - _cropView.backgroundColor = [UIColor clearColor];
280   - _cropView.layer.borderColor = [UIColor whiteColor].CGColor;
281   - _cropView.layer.borderWidth = 1.0;
282   - if (_tzImagePickerVc.needCircleCrop) {
283   - _cropView.layer.cornerRadius = _tzImagePickerVc.cropRect.size.width / 2;
284   - _cropView.clipsToBounds = YES;
285   - }
286   - [self.view addSubview:_cropView];
287   - if (_tzImagePickerVc.cropViewSettingBlock) {
288   - _tzImagePickerVc.cropViewSettingBlock(_cropView);
289   - }
290   -
291   - [self.view bringSubviewToFront:_naviBar];
292   - [self.view bringSubviewToFront:_tipBar];
293   - [self.view bringSubviewToFront:_toolBar];
294   - }
295   -}
296   -
297   -#pragma mark - Layout
298   -
299   -- (void)viewDidLayoutSubviews {
300   - [super viewDidLayoutSubviews];
301   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
302   -
303   - CGFloat statusBarHeight = [TZCommonTools tz_statusBarHeight];
304   - CGFloat statusBarHeightInterval = statusBarHeight - 20;
305   - CGFloat naviBarHeight = statusBarHeight + _tzImagePickerVc.navigationBar.tz_height;
306   - _naviBar.frame = CGRectMake(0, 0, self.view.tz_width, naviBarHeight);
307   - _backButton.frame = CGRectMake(10, 10 + statusBarHeightInterval, 44, 44);
308   - _selectButton.frame = CGRectMake(self.view.tz_width - 56, 10 + statusBarHeightInterval, 44, 44);
309   - _indexLabel.frame = _selectButton.frame;
310   - _navBarLine.frame = CGRectMake(0, _naviBar.tz_height - 0.5, _naviBar.tz_width, 0.5);
311   -
312   - ///Lxg 提示视图约束
313   - CGFloat tipBarHeight = _tzImagePickerVc.navigationBar.tz_height;
314   - _tipBar.frame = CGRectMake(0, _naviBar.tz_bottom, _naviBar.tz_width, tipBarHeight);
315   - _tipContentLabel.frame = CGRectMake(12, 0, _tipBar.tz_width - 24, tipBarHeight);
316   -
317   - _layout.itemSize = CGSizeMake(self.view.tz_width + 20, self.view.tz_height);
318   - _layout.minimumInteritemSpacing = 0;
319   - _layout.minimumLineSpacing = 0;
320   - _collectionView.frame = CGRectMake(-10, 0, self.view.tz_width + 20, self.view.tz_height);
321   - [_collectionView setCollectionViewLayout:_layout];
322   - if (_offsetItemCount > 0) {
323   - CGFloat offsetX = _offsetItemCount * _layout.itemSize.width;
324   - [_collectionView setContentOffset:CGPointMake(offsetX, 0)];
325   - }
326   - if (_tzImagePickerVc.allowCrop) {
327   - [_collectionView reloadData];
328   - }
329   -
330   - CGFloat toolBarHeight = [TZCommonTools tz_isIPhoneX] ? 44 + (83 - 49) : 44;
331   - CGFloat toolBarTop = self.view.tz_height - toolBarHeight;
332   - _toolBar.frame = CGRectMake(0, toolBarTop, self.view.tz_width, toolBarHeight);
333   - if (_tzImagePickerVc.allowPickingOriginalPhoto) {
334   - CGFloat fullImageWidth = [_tzImagePickerVc.fullImageBtnTitleStr tz_calculateSizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:13]} maxSize:CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX)].width;
335   - _originalPhotoButton.frame = CGRectMake(0, 0, fullImageWidth + 56, 44);
336   - _originalPhotoLabel.frame = CGRectMake(fullImageWidth + 42, 0, 80, 44);
337   - }
338   - [_doneButton sizeToFit];
339   - _doneButton.frame = CGRectMake(self.view.tz_width - _doneButton.tz_width - 12, 0, _doneButton.tz_width, 44);
340   - _numberImageView.frame = CGRectMake(_doneButton.tz_left - 24 - 5, 10, 24, 24);
341   - _numberLabel.frame = _numberImageView.frame;
342   - ///LXG
343   - [_editTipButton sizeToFit];
344   - _editTipButton.frame = CGRectMake(self.view.tz_width - 44 - 12, 0, 44, 44);
345   - _editTipLable.frame = CGRectMake(12, 10, self.view.tz_width - 24 - _editTipButton.tz_width, 24);
346   -
347   - [self configCropView];
348   -
349   - if (_tzImagePickerVc.photoPreviewPageDidLayoutSubviewsBlock) {
350   - _tzImagePickerVc.photoPreviewPageDidLayoutSubviewsBlock(_collectionView, _naviBar, _backButton, _selectButton, _indexLabel, _toolBar, _originalPhotoButton, _originalPhotoLabel, _doneButton, _numberImageView, _numberLabel);
351   - }
352   -}
353   -
354   -#pragma mark - Notification
355   -
356   -- (void)didChangeStatusBarOrientationNotification:(NSNotification *)noti {
357   - _offsetItemCount = _collectionView.contentOffset.x / _layout.itemSize.width;
358   -}
359   -
360   -#pragma mark - Click Event
361   -
362   -- (void)select:(UIButton *)selectButton {
363   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
364   - TZAssetModel *model = _models[_currentIndex];
365   - ///LXG:加入当点击选择时 滑动到另一个页面 选中为当前页面判断是否可选
366   - if (!selectButton.enabled) {
367   - return;
368   - }
369   -
370   - if (!selectButton.isSelected) {
371   - // 1. select:check if over the maxImagesCount / 选择照片,检查是否超过了最大个数的限制
372   - if (_tzImagePickerVc.selectedModels.count >= _tzImagePickerVc.maxImagesCount) {
373   - NSString *title = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Select a maximum of %zd photos"], _tzImagePickerVc.maxImagesCount];
374   - [_tzImagePickerVc showAlertWithTitle:title];
375   - return;
376   - // 2. if not over the maxImagesCount / 如果没有超过最大个数限制
377   - } else {
378   - [_tzImagePickerVc addSelectedModel:model];
379   - if (self.photos) {
380   - [_tzImagePickerVc.selectedAssets addObject:_assetsTemp[_currentIndex]];
381   - [self.photos addObject:_photosTemp[_currentIndex]];
382   - }
383   - if (model.type == TZAssetModelMediaTypeVideo && !_tzImagePickerVc.allowPickingMultipleVideo) {
384   - [_tzImagePickerVc showAlertWithTitle:[NSBundle tz_localizedStringForKey:@"Select the video when in multi state, we will handle the video as a photo"]];
385   - }
386   - }
387   - } else {
388   - NSArray *selectedModels = [NSArray arrayWithArray:_tzImagePickerVc.selectedModels];
389   - for (TZAssetModel *model_item in selectedModels) {
390   - if ([[[TZImageManager manager] getAssetIdentifier:model.asset] isEqualToString:[[TZImageManager manager] getAssetIdentifier:model_item.asset]]) {
391   - // 1.6.7版本更新:防止有多个一样的model,一次性被移除了
392   - NSArray *selectedModelsTmp = [NSArray arrayWithArray:_tzImagePickerVc.selectedModels];
393   - for (NSInteger i = 0; i < selectedModelsTmp.count; i++) {
394   - TZAssetModel *model = selectedModelsTmp[i];
395   - if ([model isEqual:model_item]) {
396   - [_tzImagePickerVc removeSelectedModel:model];
397   - // [_tzImagePickerVc.selectedModels removeObjectAtIndex:i];
398   - break;
399   - }
400   - }
401   - if (self.photos) {
402   - // 1.6.7版本更新:防止有多个一样的asset,一次性被移除了
403   - NSArray *selectedAssetsTmp = [NSArray arrayWithArray:_tzImagePickerVc.selectedAssets];
404   - for (NSInteger i = 0; i < selectedAssetsTmp.count; i++) {
405   - id asset = selectedAssetsTmp[i];
406   - if ([asset isEqual:_assetsTemp[_currentIndex]]) {
407   - [_tzImagePickerVc.selectedAssets removeObjectAtIndex:i];
408   - break;
409   - }
410   - }
411   - // [_tzImagePickerVc.selectedAssets removeObject:_assetsTemp[_currentIndex]];
412   - [self.photos removeObject:_photosTemp[_currentIndex]];
413   - }
414   - break;
415   - }
416   - }
417   - }
418   -
419   - model.isSelected = !selectButton.isSelected;
420   - [self refreshNaviBarAndBottomBarState];
421   - if (model.isSelected) {
422   - [UIView showOscillatoryAnimationWithLayer:selectButton.imageView.layer type:TZOscillatoryAnimationToBigger];
423   - }
424   - [UIView showOscillatoryAnimationWithLayer:_numberImageView.layer type:TZOscillatoryAnimationToSmaller];
425   -}
426   -
427   -- (void)backButtonClick {
428   - if (self.navigationController.childViewControllers.count < 2) {
429   - [self.navigationController dismissViewControllerAnimated:YES completion:nil];
430   - if ([self.navigationController isKindOfClass: [TZImagePickerController class]]) {
431   - TZImagePickerController *nav = (TZImagePickerController *)self.navigationController;
432   - if (nav.imagePickerControllerDidCancelHandle) {
433   - nav.imagePickerControllerDidCancelHandle();
434   - }
435   - }
436   - return;
437   - }
438   - [self.navigationController popViewControllerAnimated:YES];
439   - if (self.backButtonClickBlock) {
440   - self.backButtonClickBlock(_isSelectOriginalPhoto);
441   - }
442   -}
443   -
444   -- (void)doneButtonClick {
445   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
446   - // 如果图片正在从iCloud同步中,提醒用户
447   - if (_progress > 0 && _progress < 1 && (_selectButton.isSelected || !_tzImagePickerVc.selectedModels.count )) {
448   - _alertView = [_tzImagePickerVc showAlertWithTitle:[NSBundle tz_localizedStringForKey:@"Synchronizing photos from iCloud"]];
449   - return;
450   - }
451   -
452   - // 如果没有选中过照片 点击确定时选中当前预览的照片
453   - if (_tzImagePickerVc.selectedModels.count == 0 && _tzImagePickerVc.minImagesCount <= 0) {
454   - TZAssetModel *model = _models[_currentIndex];
455   - [_tzImagePickerVc addSelectedModel:model];
456   - }
457   - if (_tzImagePickerVc.allowCrop) { // 裁剪状态
458   - NSIndexPath *indexPath = [NSIndexPath indexPathForItem:_currentIndex inSection:0];
459   - TZPhotoPreviewCell *cell = (TZPhotoPreviewCell *)[_collectionView cellForItemAtIndexPath:indexPath];
460   - UIImage *cropedImage = [TZImageCropManager cropImageView:cell.previewView.imageView toRect:_tzImagePickerVc.cropRect zoomScale:cell.previewView.scrollView.zoomScale containerView:self.view];
461   - if (_tzImagePickerVc.needCircleCrop) {
462   - cropedImage = [TZImageCropManager circularClipImage:cropedImage];
463   - }
464   - if (self.doneButtonClickBlockCropMode) {
465   - TZAssetModel *model = _models[_currentIndex];
466   - self.doneButtonClickBlockCropMode(cropedImage,model.asset);
467   - }
468   - } else if (self.doneButtonClickBlock) { // 非裁剪状态
469   - self.doneButtonClickBlock(_isSelectOriginalPhoto);
470   - }
471   - if (self.doneButtonClickBlockWithPreviewType) {
472   - self.doneButtonClickBlockWithPreviewType(self.photos,_tzImagePickerVc.selectedAssets,self.isSelectOriginalPhoto);
473   - }
474   -}
475   -
476   -///lxg 编辑按钮实现
477   -- (void)editVideoButtonClick{
478   -
479   - NSLog(@"开始编辑视频了");
480   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
481   - CNEditVideoController *editVideoVC = [[CNEditVideoController alloc]init];
482   - TZAssetModel *model = _models[_currentIndex];
483   - editVideoVC.model = model;
484   - editVideoVC.models = _models;
485   - editVideoVC.currentIndex = _currentIndex;
486   - editVideoVC.isCropImage = _isCropImage;
487   - __weak typeof(self) weakSelf = self;
488   -
489   - editVideoVC.doneButtonEditClickBlock = ^(BOOL isSelectOriginalPhoto) {
490   - __strong typeof(weakSelf) strongSelf = weakSelf;
491   - strongSelf.doneButtonClickBlock(isSelectOriginalPhoto);
492   -
493   - };
494   -
495   - [_tzImagePickerVc pushViewController:editVideoVC animated:NO];
496   -}
497   -
498   -- (void)originalPhotoButtonClick {
499   - _originalPhotoButton.selected = !_originalPhotoButton.isSelected;
500   - _isSelectOriginalPhoto = _originalPhotoButton.isSelected;
501   - _originalPhotoLabel.hidden = !_originalPhotoButton.isSelected;
502   - if (_isSelectOriginalPhoto) {
503   - [self showPhotoBytes];
504   - if (!_selectButton.isSelected) {
505   - // 如果当前已选择照片张数 < 最大可选张数 && 最大可选张数大于1,就选中该张图
506   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
507   - if (_tzImagePickerVc.selectedModels.count < _tzImagePickerVc.maxImagesCount && _tzImagePickerVc.showSelectBtn) {
508   - [self select:_selectButton];
509   - }
510   - }
511   - }
512   -}
513   -
514   -- (void)didTapPreviewCell {
515   - self.isHideNaviBar = !self.isHideNaviBar;
516   - _naviBar.hidden = self.isHideNaviBar;
517   - _toolBar.hidden = self.isHideNaviBar;
518   -
519   - if (_naviBar.hidden && _toolBar.hidden) {
520   - _tipBar.hidden = YES;
521   - }else{
522   - [self refreshNaviBarAndBottomBarState];
523   - }
524   -
525   -}
526   -
527   -#pragma mark - UIScrollViewDelegate
528   -
529   -- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
530   - CGFloat offSetWidth = scrollView.contentOffset.x;
531   - offSetWidth = offSetWidth + ((self.view.tz_width + 20) * 0.5);
532   -
533   - NSInteger currentIndex = offSetWidth / (self.view.tz_width + 20);
534   -
535   - if (currentIndex < _models.count && _currentIndex != currentIndex) {
536   - _currentIndex = currentIndex;
537   - [self refreshNaviBarAndBottomBarState];
538   - }
539   -
540   - [[NSNotificationCenter defaultCenter] postNotificationName:@"photoPreviewCollectionViewDidScroll" object:nil];
541   -}
542   -
543   -#pragma mark - UICollectionViewDataSource && Delegate
544   -
545   -- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
546   - return _models.count;
547   -}
548   -
549   -- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
550   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
551   - TZAssetModel *model = _models[indexPath.item];
552   -
553   - TZAssetPreviewCell *cell;
554   - __weak typeof(self) weakSelf = self;
555   -#pragma mark - 更改视频,GIF,显示
556   - if (model.type == TZAssetModelMediaTypeVideo) {
557   - cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TZVideoPreviewCell" forIndexPath:indexPath];
558   - } else if (model.type == TZAssetModelMediaTypePhotoGif && _tzImagePickerVc.allowPickingGif) {
559   - cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TZGifPreviewCell" forIndexPath:indexPath];
560   - } else {
561   - cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TZPhotoPreviewCell" forIndexPath:indexPath];
562   - TZPhotoPreviewCell *photoPreviewCell = (TZPhotoPreviewCell *)cell;
563   - photoPreviewCell.cropRect = _tzImagePickerVc.cropRect;
564   - photoPreviewCell.allowCrop = _tzImagePickerVc.allowCrop;
565   - __weak typeof(_tzImagePickerVc) weakTzImagePickerVc = _tzImagePickerVc;
566   - __weak typeof(_collectionView) weakCollectionView = _collectionView;
567   - __weak typeof(photoPreviewCell) weakCell = photoPreviewCell;
568   - [photoPreviewCell setImageProgressUpdateBlock:^(double progress) {
569   - __strong typeof(weakSelf) strongSelf = weakSelf;
570   - __strong typeof(weakTzImagePickerVc) strongTzImagePickerVc = weakTzImagePickerVc;
571   - __strong typeof(weakCollectionView) strongCollectionView = weakCollectionView;
572   - __strong typeof(weakCell) strongCell = weakCell;
573   - strongSelf.progress = progress;
574   - if (progress >= 1) {
575   - if (strongSelf.isSelectOriginalPhoto) [strongSelf showPhotoBytes];
576   - if (strongSelf.alertView && [strongCollectionView.visibleCells containsObject:strongCell]) {
577   - [strongTzImagePickerVc hideAlertView:strongSelf.alertView];
578   - strongSelf.alertView = nil;
579   - [strongSelf doneButtonClick];
580   - }
581   - }
582   - }];
583   - }
584   -
585   - cell.model = model;
586   - [cell setSingleTapGestureBlock:^{
587   - __strong typeof(weakSelf) strongSelf = weakSelf;
588   - [strongSelf didTapPreviewCell];
589   - }];
590   - return cell;
591   -}
592   -
593   -- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
594   - if ([cell isKindOfClass:[TZPhotoPreviewCell class]]) {
595   - [(TZPhotoPreviewCell *)cell recoverSubviews];
596   - }
597   -}
598   -
599   -- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
600   - if ([cell isKindOfClass:[TZPhotoPreviewCell class]]) {
601   - [(TZPhotoPreviewCell *)cell recoverSubviews];
602   - } else if ([cell isKindOfClass:[TZVideoPreviewCell class]]) {
603   - [(TZVideoPreviewCell *)cell pausePlayerAndShowNaviBar];
604   - }
605   -}
606   -
607   -#pragma mark - Private Method
608   -
609   -- (void)dealloc {
610   - // NSLog(@"%@ dealloc",NSStringFromClass(self.class));
611   -}
612   -
613   -- (void)refreshNaviBarAndBottomBarState {
614   -
615   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
616   - TZAssetModel *model = _models[_currentIndex];
617   - _selectButton.selected = model.isSelected;
618   - [self refreshSelectButtonImageViewContentMode];
619   - if (_selectButton.isSelected && _tzImagePickerVc.showSelectedIndex && _tzImagePickerVc.showSelectBtn) {
620   - NSString *assetId = [[TZImageManager manager] getAssetIdentifier:model.asset];
621   - NSString *index = [NSString stringWithFormat:@"%zd", [_tzImagePickerVc.selectedAssetIds indexOfObject:assetId] + 1];
622   - _indexLabel.text = index;
623   - _indexLabel.hidden = NO;
624   - } else {
625   - _indexLabel.hidden = YES;
626   - }
627   - _numberLabel.text = [NSString stringWithFormat:@"%zd",_tzImagePickerVc.selectedModels.count];
628   - _numberImageView.hidden = (_tzImagePickerVc.selectedModels.count <= 0 || _isHideNaviBar || _isCropImage);
629   - _numberLabel.hidden = (_tzImagePickerVc.selectedModels.count <= 0 || _isHideNaviBar || _isCropImage);
630   -#pragma mark - ADD: 选择图片个数显示(LXG)
631   - //隐藏图标
632   - _numberLabel.hidden = YES;
633   - _numberImageView.hidden = YES;
634   - NSString *titleStr = _tzImagePickerVc.selectedModels.count > 0 ? [NSString stringWithFormat:@"完成(%zd)",_tzImagePickerVc.selectedModels.count] : @"完成";
635   - [_doneButton setTitle:titleStr forState:UIControlStateNormal];
636   - _originalPhotoButton.selected = _isSelectOriginalPhoto;
637   - _originalPhotoLabel.hidden = !_originalPhotoButton.isSelected;
638   - if (_isSelectOriginalPhoto) [self showPhotoBytes];
639   -
640   - // If is previewing video, hide original photo button
641   - // 如果正在预览的是视频,隐藏原图按钮
642   - if (!_isHideNaviBar) {
643   - if (model.type == TZAssetModelMediaTypeVideo) {
644   - _originalPhotoButton.hidden = YES;
645   - _originalPhotoLabel.hidden = YES;
646   - } else {
647   - _originalPhotoButton.hidden = NO;
648   - if (_isSelectOriginalPhoto) _originalPhotoLabel.hidden = NO;
649   - }
650   - }
651   -
652   - _doneButton.hidden = NO;
653   - _selectButton.hidden = !_tzImagePickerVc.showSelectBtn;
654   - // 让宽度/高度小于 最小可选照片尺寸 的图片不能选中
655   - if (![[TZImageManager manager] isPhotoSelectableWithAsset:model.asset]) {
656   - _numberLabel.hidden = YES;
657   - _numberImageView.hidden = YES;
658   - _selectButton.hidden = YES;
659   - _originalPhotoButton.hidden = YES;
660   - _originalPhotoLabel.hidden = YES;
661   - _doneButton.hidden = YES;
662   - }
663   -
664   -#pragma mark - ADD: 视频显示操作(LXG)
665   - //多选状态下**不允许**图片和视频混选
666   - if (!_tzImagePickerVc.allowPickingMultipleVideo) {
667   -
668   - if (model.type == TZAssetModelMediaTypeVideo) {//多选状态下**不允许**图片和视频混选 -> 视频
669   -
670   - TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
671   - if (_tzImagePickerVc.selectedModels.count > 0) {//当选择图片大于0时
672   - TZAssetModel *model = _tzImagePickerVc.selectedModels[0];
673   - if (model.type == TZAssetModelMediaTypePhoto
674   - || model.type == TZAssetModelMediaTypePhotoGif
675   - ||model.type == TZAssetModelMediaTypeLivePhoto) {//选择为图片时
676   -
677   - _selectButton.hidden = YES;
678   - _selectButton.enabled = NO;
679   - _navBarLine.hidden = NO;
680   - _tipBar.hidden = NO;
681   - _tipContentLabel.text = @"选择照片时不能选择视频";
682   - _doneButton.hidden = NO;
683   - _doneButton.enabled = YES;
684   - _editTipButton.hidden = YES;
685   - _editTipLable.hidden = YES;
686   -
687   - }else{//未来可能是语音
688   -
689   - _selectButton.hidden = YES;
690   - _selectButton.enabled = NO;
691   - _navBarLine.hidden = NO;
692   - _tipBar.hidden = NO;
693   - _tipContentLabel.text = @"选择照片时不能选择音频";
694   - _doneButton.hidden = NO;
695   - _doneButton.enabled = YES;
696   - _editTipButton.hidden = YES;
697   - _editTipLable.hidden = YES;
698   -
699   - }
700   - }else{//当选择图片==0时
701   -
702   - NSTimeInterval duration = 0.0;
703   - if ([model.asset isKindOfClass:[PHAsset class]]) {
704   - PHAsset *asset = model.asset;
705   - duration = asset.duration;
706   - }else if ([model.asset isKindOfClass:[ALAsset class]]){
707   - duration = [[model.asset valueForProperty:ALAssetPropertyDuration] doubleValue];
708   - }
709   -
710   - if (duration > _tzImagePickerVc.maxVideoDuration) {//视频长度>最大限制长度
711   -
712   - NSInteger minutes = _tzImagePickerVc.maxVideoDuration / 60;
713   - NSInteger seconds = _tzImagePickerVc.maxVideoDuration % 60;
714   - NSString *timeStr = [NSString string];
715   - if (minutes == 0) {
716   - timeStr = [NSString stringWithFormat:@"不能分享超过%li秒视频",(long)seconds];
717   - }else if (seconds == 0){
718   - timeStr = [NSString stringWithFormat:@"不能分享超过%li分视频",(long)minutes];
719   - }else{
720   - timeStr = [NSString stringWithFormat:@"不能分享超过%li分%li秒视频",(long)minutes,(long)seconds];
721   - }
722   - _tipContentLabel.text = timeStr;
723   -
724   - //当选择图片==0时,视频长度>最大限制长度
725   - _selectButton.hidden = YES;
726   - _selectButton.enabled = NO;
727   - _navBarLine.hidden = NO;
728   - _tipBar.hidden = NO;
729   - _tipContentLabel.text = timeStr;
730   - _doneButton.hidden = NO;
731   - if (_tzImagePickerVc.selectedModels.count > 0) {
732   - _doneButton.enabled = YES;
733   - }else{
734   - _doneButton.enabled = NO;
735   - }
736   - _editTipButton.hidden = YES;
737   - _editTipLable.hidden = YES;
738   -
739   - }else if(duration <= _tzImagePickerVc.maxVideoDuration && duration > _tzImagePickerVc.maxEditVideoTime){//视频长度<=最大限制长度,视频长度>=最小限制长度
740   -
741   - NSInteger minutes = _tzImagePickerVc.maxEditVideoTime / 60;
742   - NSInteger seconds = _tzImagePickerVc.maxEditVideoTime % 60;
743   - NSString *timeStr = [NSString string];
744   - if (minutes == 0) {
745   - timeStr = [NSString stringWithFormat:@"朋友圈只能分享%li秒限制的视频,需进行编辑",(long)seconds];
746   - }else if (seconds == 0){
747   - timeStr = [NSString stringWithFormat:@"朋友圈只能分享%li分限制的视频,需进行编辑",(long)minutes];
748   - }else{
749   - timeStr = [NSString stringWithFormat:@"朋友圈只能分享%li分%li秒限制的视频,需进行编辑",(long)minutes,(long)seconds];
750   - }
751   - _editTipLable.text = timeStr;
752   - //当选择图片==0时,视频长度<=最大限制长度,视频长度>最大分享长度
753   - _selectButton.hidden = YES;
754   - _selectButton.enabled = NO;
755   - _navBarLine.hidden = YES;
756   - _tipBar.hidden = YES;
757   - _tipContentLabel.text = timeStr;
758   - _doneButton.hidden = YES;
759   - _doneButton.enabled = YES;
760   - _editTipButton.hidden = NO;
761   - _editTipLable.hidden = NO;
762   -
763   - }else{//视频长度<=最大分享长度
764   - //当选择图片==0时,视频长度<=最大分享长度
765   - _selectButton.hidden = YES;
766   - _selectButton.enabled = NO;
767   - _navBarLine.hidden = YES;
768   - _tipBar.hidden = YES;
769   - _doneButton.hidden = NO;
770   - _doneButton.enabled = YES;
771   - _editTipButton.hidden = YES;
772   - _editTipLable.hidden = YES;
773   - }
774   - }
775   -
776   - } else {//滑动到不是视频时
777   - //滑动到不是视频时
778   - _selectButton.hidden = NO;
779   - _selectButton.enabled = YES;
780   - _navBarLine.hidden = YES;
781   - _tipBar.hidden = YES;
782   - _doneButton.hidden = NO;
783   - _doneButton.enabled = YES;
784   - _editTipButton.hidden = YES;
785   - _editTipLable.hidden = YES;
786   -
787   - }
788   - }else{///多选状态下**允许**图片和视频混选(lxg)
789   - NSTimeInterval duration = 0.0;
790   - if ([model.asset isKindOfClass:[PHAsset class]]) {
791   - PHAsset *asset = model.asset;
792   - duration = asset.duration;
793   - }else if([model.asset isKindOfClass:[ALAsset class]]) {
794   - duration = [[model.asset valueForProperty:ALAssetPropertyDuration] doubleValue];
795   - }
796   - if (model.type == TZAssetModelMediaTypeVideo
797   - && duration > _tzImagePickerVc.maxVideoDuration) {//视频,支持混选,时长超过最大时长限制
798   - NSInteger minutes = _tzImagePickerVc.maxVideoDuration / 60;
799   - NSInteger seconds = _tzImagePickerVc.maxVideoDuration % 60;
800   - NSString *timeStr = [NSString string];
801   - if (minutes == 0) {
802   - timeStr = [NSString stringWithFormat:@"不能选择超过%li秒视频",(long)seconds];
803   - }else if (seconds == 0){
804   - timeStr = [NSString stringWithFormat:@"不能选择超过%li分视频",(long)minutes];
805   - }else{
806   - timeStr = [NSString stringWithFormat:@"不能选择超过%li分%li秒视频",(long)minutes,(long)seconds];
807   - }
808   -
809   - _selectButton.hidden = YES;
810   - _selectButton.enabled = NO;
811   - _selectButton.enabled = NO;
812   - _navBarLine.hidden = NO;
813   - _tipBar.hidden = NO;
814   - _tipContentLabel.text = timeStr;
815   - _doneButton.hidden = NO;
816   - if (_tzImagePickerVc.selectedModels.count > 0) {
817   - _doneButton.enabled = YES;
818   - }else{
819   - _doneButton.enabled = NO;
820   - }
821   - _editTipButton.hidden = YES;
822   - _editTipLable.hidden = YES;
823   -
824   -
825   - }else{///多选状态下**允许**图片和视频混选(lxg) - 不是视频 || 视频<= _tzImagePickerVc.maxVideoDuration 最大时长限制
826   -
827   - _selectButton.hidden = NO;
828   - _selectButton.enabled = YES;
829   - _navBarLine.hidden = YES;
830   - _tipBar.hidden = YES;
831   - _doneButton.hidden = NO;
832   - _doneButton.enabled = YES;
833   - _editTipButton.hidden = YES;
834   - _editTipLable.hidden = YES;
835   -
836   - }
837   - }
838   -
839   -}
840   -
841   -- (void)refreshSelectButtonImageViewContentMode {
842   - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
843   - if (self->_selectButton.imageView.image.size.width <= 27) {
844   - self->_selectButton.imageView.contentMode = UIViewContentModeCenter;
845   - } else {
846   - self->_selectButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
847   - }
848   - });
849   -}
850   -
851   -- (void)showPhotoBytes {
852   - [[TZImageManager manager] getPhotosBytesWithArray:@[_models[_currentIndex]] completion:^(NSString *totalBytes) {
853   - self->_originalPhotoLabel.text = [NSString stringWithFormat:@"(%@)",totalBytes];
854   - }];
855   -}
856   -
857   -@end
CNLiveImagePickerController/TZProgressView.h deleted 100755 → 0
1   -//
2   -// TZProgressView.h
3   -// TZImagePickerController
4   -//
5   -// Created by ttouch on 2016/12/6.
6   -// Copyright © 2016年 谭真. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -@interface TZProgressView : UIView
12   -
13   -@property (nonatomic, assign) double progress;
14   -
15   -@end
CNLiveImagePickerController/TZProgressView.m deleted 100755 → 0
1   -//
2   -// TZProgressView.m
3   -// TZImagePickerController
4   -//
5   -// Created by ttouch on 2016/12/6.
6   -// Copyright © 2016年 谭真. All rights reserved.
7   -//
8   -
9   -#import "TZProgressView.h"
10   -
11   -@interface TZProgressView ()
12   -@property (nonatomic, strong) CAShapeLayer *progressLayer;
13   -@end
14   -
15   -@implementation TZProgressView
16   -
17   -- (instancetype)init {
18   - self = [super init];
19   - if (self) {
20   - self.backgroundColor = [UIColor clearColor];
21   -
22   - _progressLayer = [CAShapeLayer layer];
23   - _progressLayer.fillColor = [[UIColor clearColor] CGColor];
24   - _progressLayer.strokeColor = [[UIColor whiteColor] CGColor];
25   - _progressLayer.opacity = 1;
26   - _progressLayer.lineCap = kCALineCapRound;
27   - _progressLayer.lineWidth = 5;
28   -
29   - [_progressLayer setShadowColor:[UIColor blackColor].CGColor];
30   - [_progressLayer setShadowOffset:CGSizeMake(1, 1)];
31   - [_progressLayer setShadowOpacity:0.5];
32   - [_progressLayer setShadowRadius:2];
33   - }
34   - return self;
35   -}
36   -
37   -- (void)drawRect:(CGRect)rect {
38   - CGPoint center = CGPointMake(rect.size.width / 2, rect.size.height / 2);
39   - CGFloat radius = rect.size.width / 2;
40   - CGFloat startA = - M_PI_2;
41   - CGFloat endA = - M_PI_2 + M_PI * 2 * _progress;
42   - _progressLayer.frame = self.bounds;
43   - UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
44   - _progressLayer.path =[path CGPath];
45   -
46   - [_progressLayer removeFromSuperlayer];
47   - [self.layer addSublayer:_progressLayer];
48   -}
49   -
50   -- (void)setProgress:(double)progress {
51   - _progress = progress;
52   - [self setNeedsDisplay];
53   -}
54   -
55   -@end
CNLiveImagePickerController/TZVideoPlayerController.h deleted 100755 → 0
1   -//
2   -// TZVideoPlayerController.h
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 16/1/5.
6   -// Copyright © 2016年 谭真. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -@class TZAssetModel;
12   -@interface TZVideoPlayerController : UIViewController
13   -
14   -@property (nonatomic, strong) TZAssetModel *model;
15   -///其他进入和相册进入(lxg)
16   -@property (nonatomic, assign) BOOL isOther;
17   -
18   -@end
CNLiveImagePickerController/TZVideoPlayerController.m deleted 100755 → 0
1   -//
2   -// TZVideoPlayerController.m
3   -// TZImagePickerController
4   -//
5   -// Created by 谭真 on 16/1/5.
6   -// Copyright © 2016年 谭真. All rights reserved.
7   -//
8   -
9   -#import "TZVideoPlayerController.h"
10   -#import <MediaPlayer/MediaPlayer.h>
11   -#import "UIView+Layout.h"
12   -#import "TZImageManager.h"
13   -#import "TZAssetModel.h"
14   -#import "TZImagePickerController.h"
15   -#import "TZPhotoPreviewController.h"
16   -
17   -@interface TZVideoPlayerController () {
18   - AVPlayer *_player;
19   - AVPlayerLayer *_playerLayer;
20   - UIButton *_playButton;
21   - UIImage *_cover;
22   - ///LXG nav属性
23   - UIView *_naviBar;
24   - UIButton *_backButton;
25   -
26   - UIView *_toolBar;
27   - UIButton *_doneButton;
28   - UIProgressView *_progress;
29   -
30   - UIStatusBarStyle _originStatusBarStyle;
31   -}
32   -@property (assign, nonatomic) BOOL needShowStatusBar;
33   -@end
34   -
35   -#pragma clang diagnostic push
36   -#pragma clang diagnostic ignored "-Wdeprecated-declarations"
37   -
38   -@implementation TZVideoPlayerController
39   -
40   -- (void)viewDidLoad {
41   - [super viewDidLoad];
42   - ///LXG 注释
43   -// self.needShowStatusBar = ![UIApplication sharedApplication].statusBarHidden;
44   - self.view.backgroundColor = [UIColor blackColor];
45   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
46   - if (tzImagePickerVc) {
47   - self.navigationItem.title = tzImagePickerVc.previewBtnTitleStr;
48   - }
49   - [self configMoviePlayer];
50   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pausePlayerAndShowNaviBar) name:UIApplicationWillResignActiveNotification object:nil];
51   -}
52   -#pragma mark - ADD: 导航栏(LXG)
53   -- (void)viewWillAppear:(BOOL)animated {
54   - [super viewWillAppear:animated];
55   - _originStatusBarStyle = [UIApplication sharedApplication].statusBarStyle;
56   - ///LXG 导航栏隐藏
57   - [UIApplication sharedApplication].statusBarStyle = iOS7Later ? UIStatusBarStyleLightContent : UIStatusBarStyleBlackOpaque;
58   - [self.navigationController setNavigationBarHidden:YES animated:YES];
59   - if (iOS7Later) [UIApplication sharedApplication].statusBarHidden = YES;
60   -}
61   -
62   -- (void)viewWillDisappear:(BOOL)animated {
63   - [super viewWillDisappear:animated];
64   - ///LXG 导航栏显示
65   - [UIApplication sharedApplication].statusBarStyle = _originStatusBarStyle;
66   - [self.navigationController setNavigationBarHidden:NO animated:YES];
67   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
68   - if (tzImagePickerVc.needShowStatusBar && iOS7Later) {
69   - [UIApplication sharedApplication].statusBarHidden = NO;
70   - }
71   - [TZImageManager manager].shouldFixOrientation = NO;
72   -}
73   -///LXG iOS7之后使用
74   -- (BOOL)prefersStatusBarHidden {
75   - return YES;
76   -}
77   -
78   -- (void)configMoviePlayer {
79   - [[TZImageManager manager] getPhotoWithAsset:_model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
80   - if (!isDegraded && photo) {
81   - self->_cover = photo;
82   - self->_doneButton.enabled = YES;
83   - }
84   - }];
85   - [[TZImageManager manager] getVideoWithAsset:_model.asset completion:^(AVPlayerItem *playerItem, NSDictionary *info) {
86   - dispatch_async(dispatch_get_main_queue(), ^{
87   - self->_player = [AVPlayer playerWithPlayerItem:playerItem];
88   - self->_playerLayer = [AVPlayerLayer playerLayerWithPlayer:self->_player];
89   - self->_playerLayer.frame = self.view.bounds;
90   - [self.view.layer addSublayer:self->_playerLayer];
91   - [self addProgressObserver];
92   - [self configCustomNaviBar];
93   - [self configPlayButton];
94   - [self configBottomToolBar];
95   - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pausePlayerAndShowNaviBar) name:AVPlayerItemDidPlayToEndTimeNotification object:self->_player.currentItem];
96   - });
97   - }];
98   -}
99   -
100   -/// Show progress,do it next time / 给播放器添加进度更新,下次加上
101   -- (void)addProgressObserver{
102   - AVPlayerItem *playerItem = _player.currentItem;
103   - UIProgressView *progress = _progress;
104   - [_player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
105   - float current = CMTimeGetSeconds(time);
106   - float total = CMTimeGetSeconds([playerItem duration]);
107   - if (current) {
108   - [progress setProgress:(current/total) animated:YES];
109   - }
110   - }];
111   -}
112   -
113   -- (void)configPlayButton {
114   - _playButton = [UIButton buttonWithType:UIButtonTypeCustom];
115   - [_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
116   - [_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlayHL"] forState:UIControlStateHighlighted];
117   - [_playButton addTarget:self action:@selector(playButtonClick) forControlEvents:UIControlEventTouchUpInside];
118   - [self.view addSubview:_playButton];
119   -}
120   -///XLG 自定义NAV
121   -- (void)configCustomNaviBar {
122   -
123   - _naviBar = [[UIView alloc] initWithFrame:CGRectZero];
124   - _naviBar.backgroundColor = [UIColor colorWithRed:(34/255.0) green:(34/255.0) blue:(34/255.0) alpha:0.7];
125   -
126   - _backButton = [[UIButton alloc] initWithFrame:CGRectZero];
127   - [_backButton setImage:[UIImage imageNamedFromMyBundle:@"navi_back"] forState:UIControlStateNormal];
128   - [_backButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
129   - [_backButton addTarget:self action:@selector(backButtonClick) forControlEvents:UIControlEventTouchUpInside];
130   -
131   - [_naviBar addSubview:_backButton];
132   - [self.view addSubview:_naviBar];
133   -}
134   -
135   -
136   -
137   -- (void)configBottomToolBar {
138   - _toolBar = [[UIView alloc] initWithFrame:CGRectZero];
139   - CGFloat rgb = 34 / 255.0;
140   - _toolBar.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:0.7];
141   -
142   - _doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
143   - _doneButton.titleLabel.font = [UIFont systemFontOfSize:16];
144   - if (!_cover) {
145   - _doneButton.enabled = NO;
146   - }
147   - [_doneButton addTarget:self action:@selector(doneButtonClick) forControlEvents:UIControlEventTouchUpInside];
148   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
149   - if (tzImagePickerVc) {
150   - [_doneButton setTitle:tzImagePickerVc.doneBtnTitleStr forState:UIControlStateNormal];
151   - [_doneButton setTitleColor:tzImagePickerVc.oKButtonTitleColorNormal forState:UIControlStateNormal];
152   - } else {
153   - [_doneButton setTitle:[NSBundle tz_localizedStringForKey:@"Done"] forState:UIControlStateNormal];
154   - [_doneButton setTitleColor:[UIColor colorWithRed:(83/255.0) green:(179/255.0) blue:(17/255.0) alpha:1.0] forState:UIControlStateNormal];
155   - }
156   - [_doneButton setTitleColor:tzImagePickerVc.oKButtonTitleColorDisabled forState:UIControlStateDisabled];
157   - [_toolBar addSubview:_doneButton];
158   - [self.view addSubview:_toolBar];
159   -
160   - if (tzImagePickerVc.videoPreviewPageUIConfigBlock) {
161   - tzImagePickerVc.videoPreviewPageUIConfigBlock(_playButton, _toolBar, _doneButton);
162   - }
163   -}
164   -
165   -#pragma mark - Layout
166   -
167   -- (void)viewDidLayoutSubviews {
168   - [super viewDidLayoutSubviews];
169   -
170   - CGFloat statusBarHeight = [TZCommonTools tz_statusBarHeight];
171   - CGFloat statusBarAndNaviBarHeight = statusBarHeight + self.navigationController.navigationBar.tz_height;
172   - _playerLayer.frame = self.view.bounds;
173   - CGFloat toolBarHeight = [TZCommonTools tz_isIPhoneX] ? 44 + (83 - 49) : 44;
174   - _toolBar.frame = CGRectMake(0, self.view.tz_height - toolBarHeight, self.view.tz_width, toolBarHeight);
175   - _doneButton.frame = CGRectMake(self.view.tz_width - 44 - 12, 0, 44, 44);
176   - _playButton.frame = CGRectMake(0, statusBarAndNaviBarHeight, self.view.tz_width, self.view.tz_height - statusBarAndNaviBarHeight - toolBarHeight);
177   -
178   - TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
179   - ///LXG NAV布局
180   - if (_isOther) {
181   - CGFloat statusBarHeightInterval = statusBarHeight - 20;
182   - CGFloat naviBarHeight = statusBarHeight + 44;
183   - _naviBar.frame = CGRectMake(0, 0, self.view.tz_width, naviBarHeight);
184   - _backButton.frame = CGRectMake(10, 10 + statusBarHeightInterval, 44, 44);
185   - //完成按钮
186   - _doneButton.titleLabel.font = [UIFont systemFontOfSize:13];
187   -// [_doneButton setTitle:@"完成" forState:UIControlStateDisabled];
188   -// [_doneButton setTitleColor:RGBOF(0xFFFFFF) forState:UIControlStateDisabled];
189   -// [_doneButton setTitleColor:RGBOF(0xFFFFFF) forState:UIControlStateNormal];
190   -//
191   -// //颜色绘制成图片
192   -// UIImage *dis_image = [UIImage qmui_imageWithColor:RGBOF(0x0BBE06, 0.5)];
193   -// [_doneButton setBackgroundImage:dis_image forState:UIControlStateSelected];
194   -// UIImage *nor_image = [UIImage qmui_imageWithColor:RGBOF(0x0BBE06)];
195   -// [_doneButton setBackgroundImage:nor_image forState:UIControlStateNormal];
196   - _doneButton.layer.masksToBounds = YES;
197   - _doneButton.layer.cornerRadius = 5;
198   - CGRect frame = _toolBar.frame;
199   - _doneButton.frame = CGRectMake(frame.size.width - 60 - 13, frame.size.height /2 - 15, 60, 30);
200   -
201   - }else{
202   - CGFloat statusBarHeightInterval = statusBarHeight - 20;
203   - CGFloat naviBarHeight = statusBarHeight + tzImagePickerVc.navigationBar.tz_height;
204   - _naviBar.frame = CGRectMake(0, 0, self.view.tz_width, naviBarHeight);
205   - _backButton.frame = CGRectMake(10, 10 + statusBarHeightInterval, 44, 44);
206   - }
207   - [self.view bringSubviewToFront:_naviBar];
208   - if (tzImagePickerVc.videoPreviewPageDidLayoutSubviewsBlock) {
209   - tzImagePickerVc.videoPreviewPageDidLayoutSubviewsBlock(_playButton, _toolBar, _doneButton);
210   - }
211   -}
212   -
213   -#pragma mark - Click Event
214   -
215   -- (void)playButtonClick {
216   - CMTime currentTime = _player.currentItem.currentTime;
217   - CMTime durationTime = _player.currentItem.duration;
218   - if (_player.rate == 0.0f) {
219   - if (currentTime.value == durationTime.value) [_player.currentItem seekToTime:CMTimeMake(0, 1)];
220   - [_player play];
221   - [self.navigationController setNavigationBarHidden:YES];
222   - _toolBar.hidden = YES;
223   - ///LXG 隐藏NAV
224   - _naviBar.hidden = YES;
225   - [_playButton setImage:nil forState:UIControlStateNormal];
226   - if (iOS7Later) [UIApplication sharedApplication].statusBarHidden = YES;
227   - } else {
228   - [self pausePlayerAndShowNaviBar];
229   - }
230   -}
231   -
232   -- (void)doneButtonClick {
233   - if (self.navigationController) {
234   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
235   - if (imagePickerVc.autoDismiss) {
236   - [self.navigationController dismissViewControllerAnimated:YES completion:^{
237   - [self callDelegateMethod];
238   - }];
239   - } else {
240   - [self callDelegateMethod];
241   - }
242   - } else {
243   - [self dismissViewControllerAnimated:YES completion:^{
244   - [self callDelegateMethod];
245   - }];
246   - }
247   -}
248   -
249   -- (void)callDelegateMethod {
250   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
251   - if ([imagePickerVc.pickerDelegate respondsToSelector:@selector(imagePickerController:didFinishPickingVideo:sourceAssets:)]) {
252   - [imagePickerVc.pickerDelegate imagePickerController:imagePickerVc didFinishPickingVideo:_cover sourceAssets:_model.asset];
253   - }
254   - if (imagePickerVc.didFinishPickingVideoHandle) {
255   - imagePickerVc.didFinishPickingVideoHandle(_cover,_model.asset);
256   - }
257   -}
258   -
259   -///LXG 返回实现
260   -- (void)backButtonClick {
261   - if (self.navigationController) {
262   - TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
263   - [imagePickerVc popViewControllerAnimated:YES];
264   - } else {
265   - [self dismissViewControllerAnimated:YES completion:^{
266   -
267   - }];
268   - }
269   -}
270   -
271   -
272   -#pragma mark - Notification Method
273   -
274   -- (void)pausePlayerAndShowNaviBar {
275   - [_player pause];
276   - _toolBar.hidden = NO;
277   - _naviBar.hidden = NO;
278   -// [self.navigationController setNavigationBarHidden:NO];
279   - [_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
280   - ///LXG 注释
281   -// if (self.needShowStatusBar && iOS7Later) {
282   -// [UIApplication sharedApplication].statusBarHidden = NO;
283   -// }
284   -}
285   -
286   -- (void)dealloc {
287   - [[NSNotificationCenter defaultCenter] removeObserver:self];
288   -}
289   -
290   -#pragma clang diagnostic pop
291   -
292   -@end
CNLiveImagePickerController/UIImage+CNImagePicker.h deleted 100644 → 0
1   -//
2   -// UIImage+CNImagePicker.h
3   -// CNLiveImagePickerControllerExample
4   -//
5   -// Created by 梁星国 on 2018/10/25.
6   -// Copyright © 2018年 梁星国. All rights reserved.
7   -//
8   -
9   -#import <UIKit/UIKit.h>
10   -
11   -NS_ASSUME_NONNULL_BEGIN
12   -
13   -@interface UIImage (CNImagePicker)
14   -
15   -
16   -/**
17   - 颜色t转图片
18   -
19   - @param color 颜色
20   - @return 返回f图片
21   - */
22   -+ (UIImage *)ip_imageWithColor:(UIColor *)color;
23   -
24   -/**
25   - 颜色转图片
26   -
27   - @param color 颜色
28   - @param size 大小
29   - @param radius 圆角
30   - @return 返回图片
31   - */
32   -+ (UIImage *)ip_imageWithColor:(UIColor *)color size:(CGSize)size radius:(CGFloat)radius;
33   -
34   -
35   -
36   -@end
37   -
38   -NS_ASSUME_NONNULL_END
CNLiveImagePickerController/UIImage+CNImagePicker.m deleted 100644 → 0
1   -//
2   -// UIImage+CNImagePicker.m
3   -// CNLiveImagePickerControllerExample
4   -//
5   -// Created by 梁星国 on 2018/10/25.
6   -// Copyright © 2018年 梁星国. All rights reserved.
7   -//
8   -
9   -#import "UIImage+CNImagePicker.h"
10   -
11   -@implementation UIImage (CNImagePicker)
12   -
13   -+ (UIImage *)ip_imageWithColor:(UIColor *)color {
14   - return [UIImage ip_imageWithColor:color size:CGSizeMake(4, 4) radius:0];
15   -}
16   -
17   -/**
18   - 颜色转图片
19   -
20   - @param color 颜色
21   - @param size 大小
22   - @param radius 圆角
23   - @return 返回图片
24   - */
25   -+ (UIImage *)ip_imageWithColor:(UIColor *)color size:(CGSize)size radius:(CGFloat)radius {
26   - CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
27   - UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
28   - CGContextRef context = UIGraphicsGetCurrentContext();
29   - CGContextSetFillColorWithColor(context, [color CGColor]);
30   - UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
31   - CGContextAddPath(context, path.CGPath);
32   - CGContextFillPath(context);
33   - UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
34   - UIGraphicsEndImageContext();
35   - return image;
36   -}
37   -
38   -
39   -
40   -
41   -
42   -@end
CNLiveImagePickerController/UIView+Layout.h deleted 100755 → 0
1   -//
2   -// UIView+Layout.h
3   -//
4   -// Created by 谭真 on 15/2/24.
5   -// Copyright © 2015年 谭真. All rights reserved.
6   -//
7   -
8   -#import <UIKit/UIKit.h>
9   -
10   -typedef enum : NSUInteger {
11   - TZOscillatoryAnimationToBigger,
12   - TZOscillatoryAnimationToSmaller,
13   -} TZOscillatoryAnimationType;
14   -
15   -@interface UIView (Layout)
16   -
17   -@property (nonatomic) CGFloat tz_left; ///< Shortcut for frame.origin.x.
18   -@property (nonatomic) CGFloat tz_top; ///< Shortcut for frame.origin.y
19   -@property (nonatomic) CGFloat tz_right; ///< Shortcut for frame.origin.x + frame.size.width
20   -@property (nonatomic) CGFloat tz_bottom; ///< Shortcut for frame.origin.y + frame.size.height
21   -@property (nonatomic) CGFloat tz_width; ///< Shortcut for frame.size.width.
22   -@property (nonatomic) CGFloat tz_height; ///< Shortcut for frame.size.height.
23   -@property (nonatomic) CGFloat tz_centerX; ///< Shortcut for center.x
24   -@property (nonatomic) CGFloat tz_centerY; ///< Shortcut for center.y
25   -@property (nonatomic) CGPoint tz_origin; ///< Shortcut for frame.origin.
26   -@property (nonatomic) CGSize tz_size; ///< Shortcut for frame.size.
27   -
28   -+ (void)showOscillatoryAnimationWithLayer:(CALayer *)layer type:(TZOscillatoryAnimationType)type;
29   -
30   -@end
CNLiveImagePickerController/UIView+Layout.m deleted 100755 → 0
1   -//
2   -// UIView+Layout.m
3   -//
4   -// Created by 谭真 on 15/2/24.
5   -// Copyright © 2015年 谭真. All rights reserved.
6   -//
7   -
8   -#import "UIView+Layout.h"
9   -
10   -@implementation UIView (Layout)
11   -
12   -- (CGFloat)tz_left {
13   - return self.frame.origin.x;
14   -}
15   -
16   -- (void)setTz_left:(CGFloat)x {
17   - CGRect frame = self.frame;
18   - frame.origin.x = x;
19   - self.frame = frame;
20   -}
21   -
22   -- (CGFloat)tz_top {
23   - return self.frame.origin.y;
24   -}
25   -
26   -- (void)setTz_top:(CGFloat)y {
27   - CGRect frame = self.frame;
28   - frame.origin.y = y;
29   - self.frame = frame;
30   -}
31   -
32   -- (CGFloat)tz_right {
33   - return self.frame.origin.x + self.frame.size.width;
34   -}
35   -
36   -- (void)setTz_right:(CGFloat)right {
37   - CGRect frame = self.frame;
38   - frame.origin.x = right - frame.size.width;
39   - self.frame = frame;
40   -}
41   -
42   -- (CGFloat)tz_bottom {
43   - return self.frame.origin.y + self.frame.size.height;
44   -}
45   -
46   -- (void)setTz_bottom:(CGFloat)bottom {
47   - CGRect frame = self.frame;
48   - frame.origin.y = bottom - frame.size.height;
49   - self.frame = frame;
50   -}
51   -
52   -- (CGFloat)tz_width {
53   - return self.frame.size.width;
54   -}
55   -
56   -- (void)setTz_width:(CGFloat)width {
57   - CGRect frame = self.frame;
58   - frame.size.width = width;
59   - self.frame = frame;
60   -}
61   -
62   -- (CGFloat)tz_height {
63   - return self.frame.size.height;
64   -}
65   -
66   -- (void)setTz_height:(CGFloat)height {
67   - CGRect frame = self.frame;
68   - frame.size.height = height;
69   - self.frame = frame;
70   -}
71   -
72   -- (CGFloat)tz_centerX {
73   - return self.center.x;
74   -}
75   -
76   -- (void)setTz_centerX:(CGFloat)centerX {
77   - self.center = CGPointMake(centerX, self.center.y);
78   -}
79   -
80   -- (CGFloat)tz_centerY {
81   - return self.center.y;
82   -}
83   -
84   -- (void)setTz_centerY:(CGFloat)centerY {
85   - self.center = CGPointMake(self.center.x, centerY);
86   -}
87   -
88   -- (CGPoint)tz_origin {
89   - return self.frame.origin;
90   -}
91   -
92   -- (void)setTz_origin:(CGPoint)origin {
93   - CGRect frame = self.frame;
94   - frame.origin = origin;
95   - self.frame = frame;
96   -}
97   -
98   -- (CGSize)tz_size {
99   - return self.frame.size;
100   -}
101   -
102   -- (void)setTz_size:(CGSize)size {
103   - CGRect frame = self.frame;
104   - frame.size = size;
105   - self.frame = frame;
106   -}
107   -
108   -+ (void)showOscillatoryAnimationWithLayer:(CALayer *)layer type:(TZOscillatoryAnimationType)type{
109   - NSNumber *animationScale1 = type == TZOscillatoryAnimationToBigger ? @(1.15) : @(0.5);
110   - NSNumber *animationScale2 = type == TZOscillatoryAnimationToBigger ? @(0.92) : @(1.15);
111   -
112   - [UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut animations:^{
113   - [layer setValue:animationScale1 forKeyPath:@"transform.scale"];
114   - } completion:^(BOOL finished) {
115   - [UIView animateWithDuration:0.15 delay:0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut animations:^{
116   - [layer setValue:animationScale2 forKeyPath:@"transform.scale"];
117   - } completion:^(BOOL finished) {
118   - [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut animations:^{
119   - [layer setValue:@(1.0) forKeyPath:@"transform.scale"];
120   - } completion:nil];
121   - }];
122   - }];
123   -}
124   -
125   -@end
Example/CNLiveImagePickerController.xcodeproj/project.pbxproj 0 → 100644
  1 +// !$*UTF8*$!
  2 +{
  3 + archiveVersion = 1;
  4 + classes = {
  5 + };
  6 + objectVersion = 46;
  7 + objects = {
  8 +
  9 +/* Begin PBXBuildFile section */
  10 + 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
  11 + 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; };
  12 + 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
  13 + 6003F598195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F596195388D20070C39A /* InfoPlist.strings */; };
  14 + 6003F59A195388D20070C39A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F599195388D20070C39A /* main.m */; };
  15 + 6003F59E195388D20070C39A /* CNLiveAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* CNLiveAppDelegate.m */; };
  16 + 6003F5A7195388D20070C39A /* CNLiveViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5A6195388D20070C39A /* CNLiveViewController.m */; };
  17 + 6003F5A9195388D20070C39A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5A8195388D20070C39A /* Images.xcassets */; };
  18 + 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; };
  19 + 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
  20 + 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
  21 + 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; };
  22 + 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; };
  23 + 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */; };
  24 + 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; };
  25 + 92BF8970BCB1F2976CC0C9C9 /* Pods_CNLiveImagePickerController_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6774261442B1D13201144A37 /* Pods_CNLiveImagePickerController_Tests.framework */; };
  26 + FE74180484D7CEEF4A25A61A /* Pods_CNLiveImagePickerController_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4BA720C67B8EEEF52848A79 /* Pods_CNLiveImagePickerController_Example.framework */; };
  27 +/* End PBXBuildFile section */
  28 +
  29 +/* Begin PBXContainerItemProxy section */
  30 + 6003F5B3195388D20070C39A /* PBXContainerItemProxy */ = {
  31 + isa = PBXContainerItemProxy;
  32 + containerPortal = 6003F582195388D10070C39A /* Project object */;
  33 + proxyType = 1;
  34 + remoteGlobalIDString = 6003F589195388D20070C39A;
  35 + remoteInfo = CNLiveImagePickerController;
  36 + };
  37 +/* End PBXContainerItemProxy section */
  38 +
  39 +/* Begin PBXFileReference section */
  40 + 1E186CDE862673840D64652F /* CNLiveImagePickerController.podspec */ = {isa = PBXFileReference; includeInIndex = 1; name = CNLiveImagePickerController.podspec; path = ../CNLiveImagePickerController.podspec; sourceTree = "<group>"; };
  41 + 251D01DF472ED3B34CCF79D7 /* Pods-CNLiveImagePickerController_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveImagePickerController_Tests.release.xcconfig"; path = "Target Support Files/Pods-CNLiveImagePickerController_Tests/Pods-CNLiveImagePickerController_Tests.release.xcconfig"; sourceTree = "<group>"; };
  42 + 2EFBCF51E613A31E4CA39B49 /* Pods-CNLiveImagePickerController_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveImagePickerController_Example.debug.xcconfig"; path = "Target Support Files/Pods-CNLiveImagePickerController_Example/Pods-CNLiveImagePickerController_Example.debug.xcconfig"; sourceTree = "<group>"; };
  43 + 6003F58A195388D20070C39A /* CNLiveImagePickerController_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CNLiveImagePickerController_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
  44 + 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
  45 + 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
  46 + 6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
  47 + 6003F595195388D20070C39A /* CNLiveImagePickerController-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "CNLiveImagePickerController-Info.plist"; sourceTree = "<group>"; };
  48 + 6003F597195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
  49 + 6003F599195388D20070C39A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
  50 + 6003F59B195388D20070C39A /* CNLiveImagePickerController-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CNLiveImagePickerController-Prefix.pch"; sourceTree = "<group>"; };
  51 + 6003F59C195388D20070C39A /* CNLiveAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CNLiveAppDelegate.h; sourceTree = "<group>"; };
  52 + 6003F59D195388D20070C39A /* CNLiveAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CNLiveAppDelegate.m; sourceTree = "<group>"; };
  53 + 6003F5A5195388D20070C39A /* CNLiveViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CNLiveViewController.h; sourceTree = "<group>"; };
  54 + 6003F5A6195388D20070C39A /* CNLiveViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CNLiveViewController.m; sourceTree = "<group>"; };
  55 + 6003F5A8195388D20070C39A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
  56 + 6003F5AE195388D20070C39A /* CNLiveImagePickerController_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CNLiveImagePickerController_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
  57 + 6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
  58 + 6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = "<group>"; };
  59 + 6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
  60 + 6003F5BB195388D20070C39A /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = "<group>"; };
  61 + 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = "<group>"; };
  62 + 6774261442B1D13201144A37 /* Pods_CNLiveImagePickerController_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveImagePickerController_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
  63 + 71719F9E1E33DC2100824A3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
  64 + 804602CE4E7E104F5222073B /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; name = README.md; path = ../README.md; sourceTree = "<group>"; };
  65 + 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
  66 + BF0D4829B7327822E0C4146E /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; };
  67 + C188B280A1A26E9C6D19D5C6 /* Pods-CNLiveImagePickerController_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveImagePickerController_Example.release.xcconfig"; path = "Target Support Files/Pods-CNLiveImagePickerController_Example/Pods-CNLiveImagePickerController_Example.release.xcconfig"; sourceTree = "<group>"; };
  68 + E4BA720C67B8EEEF52848A79 /* Pods_CNLiveImagePickerController_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveImagePickerController_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
  69 + F2CA825BC87A414FD6AF3A37 /* Pods-CNLiveImagePickerController_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveImagePickerController_Tests.debug.xcconfig"; path = "Target Support Files/Pods-CNLiveImagePickerController_Tests/Pods-CNLiveImagePickerController_Tests.debug.xcconfig"; sourceTree = "<group>"; };
  70 +/* End PBXFileReference section */
  71 +
  72 +/* Begin PBXFrameworksBuildPhase section */
  73 + 6003F587195388D20070C39A /* Frameworks */ = {
  74 + isa = PBXFrameworksBuildPhase;
  75 + buildActionMask = 2147483647;
  76 + files = (
  77 + 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */,
  78 + 6003F592195388D20070C39A /* UIKit.framework in Frameworks */,
  79 + 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */,
  80 + FE74180484D7CEEF4A25A61A /* Pods_CNLiveImagePickerController_Example.framework in Frameworks */,
  81 + );
  82 + runOnlyForDeploymentPostprocessing = 0;
  83 + };
  84 + 6003F5AB195388D20070C39A /* Frameworks */ = {
  85 + isa = PBXFrameworksBuildPhase;
  86 + buildActionMask = 2147483647;
  87 + files = (
  88 + 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */,
  89 + 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */,
  90 + 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */,
  91 + 92BF8970BCB1F2976CC0C9C9 /* Pods_CNLiveImagePickerController_Tests.framework in Frameworks */,
  92 + );
  93 + runOnlyForDeploymentPostprocessing = 0;
  94 + };
  95 +/* End PBXFrameworksBuildPhase section */
  96 +
  97 +/* Begin PBXGroup section */
  98 + 6003F581195388D10070C39A = {
  99 + isa = PBXGroup;
  100 + children = (
  101 + 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */,
  102 + 6003F593195388D20070C39A /* Example for CNLiveImagePickerController */,
  103 + 6003F5B5195388D20070C39A /* Tests */,
  104 + 6003F58C195388D20070C39A /* Frameworks */,
  105 + 6003F58B195388D20070C39A /* Products */,
  106 + B0A737C78E5A24C5402B3679 /* Pods */,
  107 + );
  108 + sourceTree = "<group>";
  109 + };
  110 + 6003F58B195388D20070C39A /* Products */ = {
  111 + isa = PBXGroup;
  112 + children = (
  113 + 6003F58A195388D20070C39A /* CNLiveImagePickerController_Example.app */,
  114 + 6003F5AE195388D20070C39A /* CNLiveImagePickerController_Tests.xctest */,
  115 + );
  116 + name = Products;
  117 + sourceTree = "<group>";
  118 + };
  119 + 6003F58C195388D20070C39A /* Frameworks */ = {
  120 + isa = PBXGroup;
  121 + children = (
  122 + 6003F58D195388D20070C39A /* Foundation.framework */,
  123 + 6003F58F195388D20070C39A /* CoreGraphics.framework */,
  124 + 6003F591195388D20070C39A /* UIKit.framework */,
  125 + 6003F5AF195388D20070C39A /* XCTest.framework */,
  126 + E4BA720C67B8EEEF52848A79 /* Pods_CNLiveImagePickerController_Example.framework */,
  127 + 6774261442B1D13201144A37 /* Pods_CNLiveImagePickerController_Tests.framework */,
  128 + );
  129 + name = Frameworks;
  130 + sourceTree = "<group>";
  131 + };
  132 + 6003F593195388D20070C39A /* Example for CNLiveImagePickerController */ = {
  133 + isa = PBXGroup;
  134 + children = (
  135 + 6003F59C195388D20070C39A /* CNLiveAppDelegate.h */,
  136 + 6003F59D195388D20070C39A /* CNLiveAppDelegate.m */,
  137 + 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */,
  138 + 6003F5A5195388D20070C39A /* CNLiveViewController.h */,
  139 + 6003F5A6195388D20070C39A /* CNLiveViewController.m */,
  140 + 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */,
  141 + 6003F5A8195388D20070C39A /* Images.xcassets */,
  142 + 6003F594195388D20070C39A /* Supporting Files */,
  143 + );
  144 + name = "Example for CNLiveImagePickerController";
  145 + path = CNLiveImagePickerController;
  146 + sourceTree = "<group>";
  147 + };
  148 + 6003F594195388D20070C39A /* Supporting Files */ = {
  149 + isa = PBXGroup;
  150 + children = (
  151 + 6003F595195388D20070C39A /* CNLiveImagePickerController-Info.plist */,
  152 + 6003F596195388D20070C39A /* InfoPlist.strings */,
  153 + 6003F599195388D20070C39A /* main.m */,
  154 + 6003F59B195388D20070C39A /* CNLiveImagePickerController-Prefix.pch */,
  155 + );
  156 + name = "Supporting Files";
  157 + sourceTree = "<group>";
  158 + };
  159 + 6003F5B5195388D20070C39A /* Tests */ = {
  160 + isa = PBXGroup;
  161 + children = (
  162 + 6003F5BB195388D20070C39A /* Tests.m */,
  163 + 6003F5B6195388D20070C39A /* Supporting Files */,
  164 + );
  165 + path = Tests;
  166 + sourceTree = "<group>";
  167 + };
  168 + 6003F5B6195388D20070C39A /* Supporting Files */ = {
  169 + isa = PBXGroup;
  170 + children = (
  171 + 6003F5B7195388D20070C39A /* Tests-Info.plist */,
  172 + 6003F5B8195388D20070C39A /* InfoPlist.strings */,
  173 + 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */,
  174 + );
  175 + name = "Supporting Files";
  176 + sourceTree = "<group>";
  177 + };
  178 + 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = {
  179 + isa = PBXGroup;
  180 + children = (
  181 + 1E186CDE862673840D64652F /* CNLiveImagePickerController.podspec */,
  182 + 804602CE4E7E104F5222073B /* README.md */,
  183 + BF0D4829B7327822E0C4146E /* LICENSE */,
  184 + );
  185 + name = "Podspec Metadata";
  186 + sourceTree = "<group>";
  187 + };
  188 + B0A737C78E5A24C5402B3679 /* Pods */ = {
  189 + isa = PBXGroup;
  190 + children = (
  191 + 2EFBCF51E613A31E4CA39B49 /* Pods-CNLiveImagePickerController_Example.debug.xcconfig */,
  192 + C188B280A1A26E9C6D19D5C6 /* Pods-CNLiveImagePickerController_Example.release.xcconfig */,
  193 + F2CA825BC87A414FD6AF3A37 /* Pods-CNLiveImagePickerController_Tests.debug.xcconfig */,
  194 + 251D01DF472ED3B34CCF79D7 /* Pods-CNLiveImagePickerController_Tests.release.xcconfig */,
  195 + );
  196 + name = Pods;
  197 + path = Pods;
  198 + sourceTree = "<group>";
  199 + };
  200 +/* End PBXGroup section */
  201 +
  202 +/* Begin PBXNativeTarget section */
  203 + 6003F589195388D20070C39A /* CNLiveImagePickerController_Example */ = {
  204 + isa = PBXNativeTarget;
  205 + buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveImagePickerController_Example" */;
  206 + buildPhases = (
  207 + FC3031E958514B32A46A8C4B /* [CP] Check Pods Manifest.lock */,
  208 + 6003F586195388D20070C39A /* Sources */,
  209 + 6003F587195388D20070C39A /* Frameworks */,
  210 + 6003F588195388D20070C39A /* Resources */,
  211 + 483530E695F873EC8CF99467 /* [CP] Embed Pods Frameworks */,
  212 + );
  213 + buildRules = (
  214 + );
  215 + dependencies = (
  216 + );
  217 + name = CNLiveImagePickerController_Example;
  218 + productName = CNLiveImagePickerController;
  219 + productReference = 6003F58A195388D20070C39A /* CNLiveImagePickerController_Example.app */;
  220 + productType = "com.apple.product-type.application";
  221 + };
  222 + 6003F5AD195388D20070C39A /* CNLiveImagePickerController_Tests */ = {
  223 + isa = PBXNativeTarget;
  224 + buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveImagePickerController_Tests" */;
  225 + buildPhases = (
  226 + ADCF8E65BB0A5C262C53995E /* [CP] Check Pods Manifest.lock */,
  227 + 6003F5AA195388D20070C39A /* Sources */,
  228 + 6003F5AB195388D20070C39A /* Frameworks */,
  229 + 6003F5AC195388D20070C39A /* Resources */,
  230 + );
  231 + buildRules = (
  232 + );
  233 + dependencies = (
  234 + 6003F5B4195388D20070C39A /* PBXTargetDependency */,
  235 + );
  236 + name = CNLiveImagePickerController_Tests;
  237 + productName = CNLiveImagePickerControllerTests;
  238 + productReference = 6003F5AE195388D20070C39A /* CNLiveImagePickerController_Tests.xctest */;
  239 + productType = "com.apple.product-type.bundle.unit-test";
  240 + };
  241 +/* End PBXNativeTarget section */
  242 +
  243 +/* Begin PBXProject section */
  244 + 6003F582195388D10070C39A /* Project object */ = {
  245 + isa = PBXProject;
  246 + attributes = {
  247 + CLASSPREFIX = CNLive;
  248 + LastUpgradeCheck = 0720;
  249 + ORGANIZATIONNAME = jyyjkt;
  250 + TargetAttributes = {
  251 + 6003F5AD195388D20070C39A = {
  252 + TestTargetID = 6003F589195388D20070C39A;
  253 + };
  254 + };
  255 + };
  256 + buildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject "CNLiveImagePickerController" */;
  257 + compatibilityVersion = "Xcode 3.2";
  258 + developmentRegion = English;
  259 + hasScannedForEncodings = 0;
  260 + knownRegions = (
  261 + en,
  262 + Base,
  263 + );
  264 + mainGroup = 6003F581195388D10070C39A;
  265 + productRefGroup = 6003F58B195388D20070C39A /* Products */;
  266 + projectDirPath = "";
  267 + projectRoot = "";
  268 + targets = (
  269 + 6003F589195388D20070C39A /* CNLiveImagePickerController_Example */,
  270 + 6003F5AD195388D20070C39A /* CNLiveImagePickerController_Tests */,
  271 + );
  272 + };
  273 +/* End PBXProject section */
  274 +
  275 +/* Begin PBXResourcesBuildPhase section */
  276 + 6003F588195388D20070C39A /* Resources */ = {
  277 + isa = PBXResourcesBuildPhase;
  278 + buildActionMask = 2147483647;
  279 + files = (
  280 + 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */,
  281 + 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */,
  282 + 6003F5A9195388D20070C39A /* Images.xcassets in Resources */,
  283 + 6003F598195388D20070C39A /* InfoPlist.strings in Resources */,
  284 + );
  285 + runOnlyForDeploymentPostprocessing = 0;
  286 + };
  287 + 6003F5AC195388D20070C39A /* Resources */ = {
  288 + isa = PBXResourcesBuildPhase;
  289 + buildActionMask = 2147483647;
  290 + files = (
  291 + 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */,
  292 + );
  293 + runOnlyForDeploymentPostprocessing = 0;
  294 + };
  295 +/* End PBXResourcesBuildPhase section */
  296 +
  297 +/* Begin PBXShellScriptBuildPhase section */
  298 + 483530E695F873EC8CF99467 /* [CP] Embed Pods Frameworks */ = {
  299 + isa = PBXShellScriptBuildPhase;
  300 + buildActionMask = 2147483647;
  301 + files = (
  302 + );
  303 + inputPaths = (
  304 + "${PODS_ROOT}/Target Support Files/Pods-CNLiveImagePickerController_Example/Pods-CNLiveImagePickerController_Example-frameworks.sh",
  305 + "${BUILT_PRODUCTS_DIR}/CNLiveImagePickerController/CNLiveImagePickerController.framework",
  306 + );
  307 + name = "[CP] Embed Pods Frameworks";
  308 + outputPaths = (
  309 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveImagePickerController.framework",
  310 + );
  311 + runOnlyForDeploymentPostprocessing = 0;
  312 + shellPath = /bin/sh;
  313 + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-CNLiveImagePickerController_Example/Pods-CNLiveImagePickerController_Example-frameworks.sh\"\n";
  314 + showEnvVarsInLog = 0;
  315 + };
  316 + ADCF8E65BB0A5C262C53995E /* [CP] Check Pods Manifest.lock */ = {
  317 + isa = PBXShellScriptBuildPhase;
  318 + buildActionMask = 2147483647;
  319 + files = (
  320 + );
  321 + inputFileListPaths = (
  322 + );
  323 + inputPaths = (
  324 + "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
  325 + "${PODS_ROOT}/Manifest.lock",
  326 + );
  327 + name = "[CP] Check Pods Manifest.lock";
  328 + outputFileListPaths = (
  329 + );
  330 + outputPaths = (
  331 + "$(DERIVED_FILE_DIR)/Pods-CNLiveImagePickerController_Tests-checkManifestLockResult.txt",
  332 + );
  333 + runOnlyForDeploymentPostprocessing = 0;
  334 + shellPath = /bin/sh;
  335 + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
  336 + showEnvVarsInLog = 0;
  337 + };
  338 + FC3031E958514B32A46A8C4B /* [CP] Check Pods Manifest.lock */ = {
  339 + isa = PBXShellScriptBuildPhase;
  340 + buildActionMask = 2147483647;
  341 + files = (
  342 + );
  343 + inputFileListPaths = (
  344 + );
  345 + inputPaths = (
  346 + "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
  347 + "${PODS_ROOT}/Manifest.lock",
  348 + );
  349 + name = "[CP] Check Pods Manifest.lock";
  350 + outputFileListPaths = (
  351 + );
  352 + outputPaths = (
  353 + "$(DERIVED_FILE_DIR)/Pods-CNLiveImagePickerController_Example-checkManifestLockResult.txt",
  354 + );
  355 + runOnlyForDeploymentPostprocessing = 0;
  356 + shellPath = /bin/sh;
  357 + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
  358 + showEnvVarsInLog = 0;
  359 + };
  360 +/* End PBXShellScriptBuildPhase section */
  361 +
  362 +/* Begin PBXSourcesBuildPhase section */
  363 + 6003F586195388D20070C39A /* Sources */ = {
  364 + isa = PBXSourcesBuildPhase;
  365 + buildActionMask = 2147483647;
  366 + files = (
  367 + 6003F59E195388D20070C39A /* CNLiveAppDelegate.m in Sources */,
  368 + 6003F5A7195388D20070C39A /* CNLiveViewController.m in Sources */,
  369 + 6003F59A195388D20070C39A /* main.m in Sources */,
  370 + );
  371 + runOnlyForDeploymentPostprocessing = 0;
  372 + };
  373 + 6003F5AA195388D20070C39A /* Sources */ = {
  374 + isa = PBXSourcesBuildPhase;
  375 + buildActionMask = 2147483647;
  376 + files = (
  377 + 6003F5BC195388D20070C39A /* Tests.m in Sources */,
  378 + );
  379 + runOnlyForDeploymentPostprocessing = 0;
  380 + };
  381 +/* End PBXSourcesBuildPhase section */
  382 +
  383 +/* Begin PBXTargetDependency section */
  384 + 6003F5B4195388D20070C39A /* PBXTargetDependency */ = {
  385 + isa = PBXTargetDependency;
  386 + target = 6003F589195388D20070C39A /* CNLiveImagePickerController_Example */;
  387 + targetProxy = 6003F5B3195388D20070C39A /* PBXContainerItemProxy */;
  388 + };
  389 +/* End PBXTargetDependency section */
  390 +
  391 +/* Begin PBXVariantGroup section */
  392 + 6003F596195388D20070C39A /* InfoPlist.strings */ = {
  393 + isa = PBXVariantGroup;
  394 + children = (
  395 + 6003F597195388D20070C39A /* en */,
  396 + );
  397 + name = InfoPlist.strings;
  398 + sourceTree = "<group>";
  399 + };
  400 + 6003F5B8195388D20070C39A /* InfoPlist.strings */ = {
  401 + isa = PBXVariantGroup;
  402 + children = (
  403 + 6003F5B9195388D20070C39A /* en */,
  404 + );
  405 + name = InfoPlist.strings;
  406 + sourceTree = "<group>";
  407 + };
  408 + 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */ = {
  409 + isa = PBXVariantGroup;
  410 + children = (
  411 + 71719F9E1E33DC2100824A3D /* Base */,
  412 + );
  413 + name = LaunchScreen.storyboard;
  414 + sourceTree = "<group>";
  415 + };
  416 +/* End PBXVariantGroup section */
  417 +
  418 +/* Begin XCBuildConfiguration section */
  419 + 6003F5BD195388D20070C39A /* Debug */ = {
  420 + isa = XCBuildConfiguration;
  421 + buildSettings = {
  422 + ALWAYS_SEARCH_USER_PATHS = NO;
  423 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  424 + CLANG_CXX_LIBRARY = "libc++";
  425 + CLANG_ENABLE_MODULES = YES;
  426 + CLANG_ENABLE_OBJC_ARC = YES;
  427 + CLANG_WARN_BOOL_CONVERSION = YES;
  428 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  429 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  430 + CLANG_WARN_EMPTY_BODY = YES;
  431 + CLANG_WARN_ENUM_CONVERSION = YES;
  432 + CLANG_WARN_INT_CONVERSION = YES;
  433 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  434 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  435 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  436 + COPY_PHASE_STRIP = NO;
  437 + ENABLE_TESTABILITY = YES;
  438 + GCC_C_LANGUAGE_STANDARD = gnu99;
  439 + GCC_DYNAMIC_NO_PIC = NO;
  440 + GCC_OPTIMIZATION_LEVEL = 0;
  441 + GCC_PREPROCESSOR_DEFINITIONS = (
  442 + "DEBUG=1",
  443 + "$(inherited)",
  444 + );
  445 + GCC_SYMBOLS_PRIVATE_EXTERN = NO;
  446 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  447 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  448 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  449 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  450 + GCC_WARN_UNUSED_FUNCTION = YES;
  451 + GCC_WARN_UNUSED_VARIABLE = YES;
  452 + IPHONEOS_DEPLOYMENT_TARGET = 9.3;
  453 + ONLY_ACTIVE_ARCH = YES;
  454 + SDKROOT = iphoneos;
  455 + TARGETED_DEVICE_FAMILY = "1,2";
  456 + };
  457 + name = Debug;
  458 + };
  459 + 6003F5BE195388D20070C39A /* Release */ = {
  460 + isa = XCBuildConfiguration;
  461 + buildSettings = {
  462 + ALWAYS_SEARCH_USER_PATHS = NO;
  463 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  464 + CLANG_CXX_LIBRARY = "libc++";
  465 + CLANG_ENABLE_MODULES = YES;
  466 + CLANG_ENABLE_OBJC_ARC = YES;
  467 + CLANG_WARN_BOOL_CONVERSION = YES;
  468 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  469 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  470 + CLANG_WARN_EMPTY_BODY = YES;
  471 + CLANG_WARN_ENUM_CONVERSION = YES;
  472 + CLANG_WARN_INT_CONVERSION = YES;
  473 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  474 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  475 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  476 + COPY_PHASE_STRIP = YES;
  477 + ENABLE_NS_ASSERTIONS = NO;
  478 + GCC_C_LANGUAGE_STANDARD = gnu99;
  479 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  480 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  481 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  482 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  483 + GCC_WARN_UNUSED_FUNCTION = YES;
  484 + GCC_WARN_UNUSED_VARIABLE = YES;
  485 + IPHONEOS_DEPLOYMENT_TARGET = 9.3;
  486 + SDKROOT = iphoneos;
  487 + TARGETED_DEVICE_FAMILY = "1,2";
  488 + VALIDATE_PRODUCT = YES;
  489 + };
  490 + name = Release;
  491 + };
  492 + 6003F5C0195388D20070C39A /* Debug */ = {
  493 + isa = XCBuildConfiguration;
  494 + baseConfigurationReference = 2EFBCF51E613A31E4CA39B49 /* Pods-CNLiveImagePickerController_Example.debug.xcconfig */;
  495 + buildSettings = {
  496 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  497 + GCC_PRECOMPILE_PREFIX_HEADER = YES;
  498 + GCC_PREFIX_HEADER = "CNLiveImagePickerController/CNLiveImagePickerController-Prefix.pch";
  499 + INFOPLIST_FILE = "CNLiveImagePickerController/CNLiveImagePickerController-Info.plist";
  500 + MODULE_NAME = ExampleApp;
  501 + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
  502 + PRODUCT_NAME = "$(TARGET_NAME)";
  503 + SWIFT_VERSION = 4.0;
  504 + WRAPPER_EXTENSION = app;
  505 + };
  506 + name = Debug;
  507 + };
  508 + 6003F5C1195388D20070C39A /* Release */ = {
  509 + isa = XCBuildConfiguration;
  510 + baseConfigurationReference = C188B280A1A26E9C6D19D5C6 /* Pods-CNLiveImagePickerController_Example.release.xcconfig */;
  511 + buildSettings = {
  512 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  513 + GCC_PRECOMPILE_PREFIX_HEADER = YES;
  514 + GCC_PREFIX_HEADER = "CNLiveImagePickerController/CNLiveImagePickerController-Prefix.pch";
  515 + INFOPLIST_FILE = "CNLiveImagePickerController/CNLiveImagePickerController-Info.plist";
  516 + MODULE_NAME = ExampleApp;
  517 + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
  518 + PRODUCT_NAME = "$(TARGET_NAME)";
  519 + SWIFT_VERSION = 4.0;
  520 + WRAPPER_EXTENSION = app;
  521 + };
  522 + name = Release;
  523 + };
  524 + 6003F5C3195388D20070C39A /* Debug */ = {
  525 + isa = XCBuildConfiguration;
  526 + baseConfigurationReference = F2CA825BC87A414FD6AF3A37 /* Pods-CNLiveImagePickerController_Tests.debug.xcconfig */;
  527 + buildSettings = {
  528 + BUNDLE_LOADER = "$(TEST_HOST)";
  529 + FRAMEWORK_SEARCH_PATHS = (
  530 + "$(PLATFORM_DIR)/Developer/Library/Frameworks",
  531 + "$(inherited)",
  532 + "$(DEVELOPER_FRAMEWORKS_DIR)",
  533 + );
  534 + GCC_PRECOMPILE_PREFIX_HEADER = YES;
  535 + GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch";
  536 + GCC_PREPROCESSOR_DEFINITIONS = (
  537 + "DEBUG=1",
  538 + "$(inherited)",
  539 + );
  540 + INFOPLIST_FILE = "Tests/Tests-Info.plist";
  541 + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
  542 + PRODUCT_NAME = "$(TARGET_NAME)";
  543 + SWIFT_VERSION = 4.0;
  544 + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CNLiveImagePickerController_Example.app/CNLiveImagePickerController_Example";
  545 + WRAPPER_EXTENSION = xctest;
  546 + };
  547 + name = Debug;
  548 + };
  549 + 6003F5C4195388D20070C39A /* Release */ = {
  550 + isa = XCBuildConfiguration;
  551 + baseConfigurationReference = 251D01DF472ED3B34CCF79D7 /* Pods-CNLiveImagePickerController_Tests.release.xcconfig */;
  552 + buildSettings = {
  553 + BUNDLE_LOADER = "$(TEST_HOST)";
  554 + FRAMEWORK_SEARCH_PATHS = (
  555 + "$(PLATFORM_DIR)/Developer/Library/Frameworks",
  556 + "$(inherited)",
  557 + "$(DEVELOPER_FRAMEWORKS_DIR)",
  558 + );
  559 + GCC_PRECOMPILE_PREFIX_HEADER = YES;
  560 + GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch";
  561 + INFOPLIST_FILE = "Tests/Tests-Info.plist";
  562 + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
  563 + PRODUCT_NAME = "$(TARGET_NAME)";
  564 + SWIFT_VERSION = 4.0;
  565 + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CNLiveImagePickerController_Example.app/CNLiveImagePickerController_Example";
  566 + WRAPPER_EXTENSION = xctest;
  567 + };
  568 + name = Release;
  569 + };
  570 +/* End XCBuildConfiguration section */
  571 +
  572 +/* Begin XCConfigurationList section */
  573 + 6003F585195388D10070C39A /* Build configuration list for PBXProject "CNLiveImagePickerController" */ = {
  574 + isa = XCConfigurationList;
  575 + buildConfigurations = (
  576 + 6003F5BD195388D20070C39A /* Debug */,
  577 + 6003F5BE195388D20070C39A /* Release */,
  578 + );
  579 + defaultConfigurationIsVisible = 0;
  580 + defaultConfigurationName = Release;
  581 + };
  582 + 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveImagePickerController_Example" */ = {
  583 + isa = XCConfigurationList;
  584 + buildConfigurations = (
  585 + 6003F5C0195388D20070C39A /* Debug */,
  586 + 6003F5C1195388D20070C39A /* Release */,
  587 + );
  588 + defaultConfigurationIsVisible = 0;
  589 + defaultConfigurationName = Release;
  590 + };
  591 + 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveImagePickerController_Tests" */ = {
  592 + isa = XCConfigurationList;
  593 + buildConfigurations = (
  594 + 6003F5C3195388D20070C39A /* Debug */,
  595 + 6003F5C4195388D20070C39A /* Release */,
  596 + );
  597 + defaultConfigurationIsVisible = 0;
  598 + defaultConfigurationName = Release;
  599 + };
  600 +/* End XCConfigurationList section */
  601 + };
  602 + rootObject = 6003F582195388D10070C39A /* Project object */;
  603 +}
... ...
Example/CNLiveImagePickerController.xcodeproj/xcshareddata/xcschemes/CNLiveImagePickerController-Example.xcscheme 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Scheme
  3 + LastUpgradeVersion = "0720"
  4 + version = "1.3">
  5 + <BuildAction
  6 + parallelizeBuildables = "YES"
  7 + buildImplicitDependencies = "YES">
  8 + <BuildActionEntries>
  9 + <BuildActionEntry
  10 + buildForTesting = "YES"
  11 + buildForRunning = "YES"
  12 + buildForProfiling = "YES"
  13 + buildForArchiving = "YES"
  14 + buildForAnalyzing = "YES">
  15 + <BuildableReference
  16 + BuildableIdentifier = "primary"
  17 + BlueprintIdentifier = "6003F589195388D20070C39A"
  18 + BuildableName = "CNLiveImagePickerController_Example.app"
  19 + BlueprintName = "CNLiveImagePickerController_Example"
  20 + ReferencedContainer = "container:CNLiveImagePickerController.xcodeproj">
  21 + </BuildableReference>
  22 + </BuildActionEntry>
  23 + </BuildActionEntries>
  24 + </BuildAction>
  25 + <TestAction
  26 + buildConfiguration = "Debug"
  27 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  28 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  29 + shouldUseLaunchSchemeArgsEnv = "YES">
  30 + <Testables>
  31 + <TestableReference
  32 + skipped = "NO">
  33 + <BuildableReference
  34 + BuildableIdentifier = "primary"
  35 + BlueprintIdentifier = "6003F5AD195388D20070C39A"
  36 + BuildableName = "CNLiveImagePickerController_Tests.xctest"
  37 + BlueprintName = "CNLiveImagePickerController_Tests"
  38 + ReferencedContainer = "container:CNLiveImagePickerController.xcodeproj">
  39 + </BuildableReference>
  40 + </TestableReference>
  41 + </Testables>
  42 + <MacroExpansion>
  43 + <BuildableReference
  44 + BuildableIdentifier = "primary"
  45 + BlueprintIdentifier = "6003F589195388D20070C39A"
  46 + BuildableName = "CNLiveImagePickerController_Example.app"
  47 + BlueprintName = "CNLiveImagePickerController_Example"
  48 + ReferencedContainer = "container:CNLiveImagePickerController.xcodeproj">
  49 + </BuildableReference>
  50 + </MacroExpansion>
  51 + <AdditionalOptions>
  52 + </AdditionalOptions>
  53 + </TestAction>
  54 + <LaunchAction
  55 + buildConfiguration = "Debug"
  56 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  57 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  58 + launchStyle = "0"
  59 + useCustomWorkingDirectory = "NO"
  60 + ignoresPersistentStateOnLaunch = "NO"
  61 + debugDocumentVersioning = "YES"
  62 + debugServiceExtension = "internal"
  63 + allowLocationSimulation = "YES">
  64 + <BuildableProductRunnable
  65 + runnableDebuggingMode = "0">
  66 + <BuildableReference
  67 + BuildableIdentifier = "primary"
  68 + BlueprintIdentifier = "6003F589195388D20070C39A"
  69 + BuildableName = "CNLiveImagePickerController_Example.app"
  70 + BlueprintName = "CNLiveImagePickerController_Example"
  71 + ReferencedContainer = "container:CNLiveImagePickerController.xcodeproj">
  72 + </BuildableReference>
  73 + </BuildableProductRunnable>
  74 + <AdditionalOptions>
  75 + </AdditionalOptions>
  76 + </LaunchAction>
  77 + <ProfileAction
  78 + buildConfiguration = "Release"
  79 + shouldUseLaunchSchemeArgsEnv = "YES"
  80 + savedToolIdentifier = ""
  81 + useCustomWorkingDirectory = "NO"
  82 + debugDocumentVersioning = "YES">
  83 + <BuildableProductRunnable
  84 + runnableDebuggingMode = "0">
  85 + <BuildableReference
  86 + BuildableIdentifier = "primary"
  87 + BlueprintIdentifier = "6003F589195388D20070C39A"
  88 + BuildableName = "CNLiveImagePickerController_Example.app"
  89 + BlueprintName = "CNLiveImagePickerController_Example"
  90 + ReferencedContainer = "container:CNLiveImagePickerController.xcodeproj">
  91 + </BuildableReference>
  92 + </BuildableProductRunnable>
  93 + </ProfileAction>
  94 + <AnalyzeAction
  95 + buildConfiguration = "Debug">
  96 + </AnalyzeAction>
  97 + <ArchiveAction
  98 + buildConfiguration = "Release"
  99 + revealArchiveInOrganizer = "YES">
  100 + </ArchiveAction>
  101 +</Scheme>
... ...
Example/CNLiveImagePickerController/Base.lproj/LaunchScreen.storyboard 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
  3 + <device id="retina4_7" orientation="portrait">
  4 + <adaptation id="fullscreen"/>
  5 + </device>
  6 + <dependencies>
  7 + <deployment identifier="iOS"/>
  8 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
  9 + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
  10 + </dependencies>
  11 + <scenes>
  12 + <!--View Controller-->
  13 + <scene sceneID="EHf-IW-A2E">
  14 + <objects>
  15 + <viewController id="01J-lp-oVM" sceneMemberID="viewController">
  16 + <layoutGuides>
  17 + <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
  18 + <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
  19 + </layoutGuides>
  20 + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
  21 + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
  22 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  23 + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  24 + </view>
  25 + </viewController>
  26 + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
  27 + </objects>
  28 + <point key="canvasLocation" x="53" y="375"/>
  29 + </scene>
  30 + </scenes>
  31 +</document>
... ...
Example/CNLiveImagePickerController/Base.lproj/Main.storyboard 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="whP-gf-Uak">
  3 + <device id="retina4_7" orientation="portrait">
  4 + <adaptation id="fullscreen"/>
  5 + </device>
  6 + <dependencies>
  7 + <deployment identifier="iOS"/>
  8 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
  9 + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
  10 + </dependencies>
  11 + <scenes>
  12 + <!--View Controller-->
  13 + <scene sceneID="wQg-tq-qST">
  14 + <objects>
  15 + <viewController id="whP-gf-Uak" customClass="CNLiveViewController" sceneMemberID="viewController">
  16 + <layoutGuides>
  17 + <viewControllerLayoutGuide type="top" id="uEw-UM-LJ8"/>
  18 + <viewControllerLayoutGuide type="bottom" id="Mvr-aV-6Um"/>
  19 + </layoutGuides>
  20 + <view key="view" contentMode="scaleToFill" id="TpU-gO-2f1">
  21 + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
  22 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  23 + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  24 + </view>
  25 + </viewController>
  26 + <placeholder placeholderIdentifier="IBFirstResponder" id="tc2-Qw-aMS" userLabel="First Responder" sceneMemberID="firstResponder"/>
  27 + </objects>
  28 + <point key="canvasLocation" x="305" y="433"/>
  29 + </scene>
  30 + </scenes>
  31 +</document>
... ...
Example/CNLiveImagePickerController/CNLiveAppDelegate.h 0 → 100644
  1 +//
  2 +// CNLiveAppDelegate.h
  3 +// CNLiveImagePickerController
  4 +//
  5 +// Created by jyyjkt on 08/01/2019.
  6 +// Copyright (c) 2019 jyyjkt. All rights reserved.
  7 +//
  8 +
  9 +@import UIKit;
  10 +
  11 +@interface CNLiveAppDelegate : UIResponder <UIApplicationDelegate>
  12 +
  13 +@property (strong, nonatomic) UIWindow *window;
  14 +
  15 +@end
... ...
Example/CNLiveImagePickerController/CNLiveAppDelegate.m 0 → 100644
  1 +//
  2 +// CNLiveAppDelegate.m
  3 +// CNLiveImagePickerController
  4 +//
  5 +// Created by jyyjkt on 08/01/2019.
  6 +// Copyright (c) 2019 jyyjkt. All rights reserved.
  7 +//
  8 +
  9 +#import "CNLiveAppDelegate.h"
  10 +
  11 +@implementation CNLiveAppDelegate
  12 +
  13 +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  14 +{
  15 + // Override point for customization after application launch.
  16 + return YES;
  17 +}
  18 +
  19 +- (void)applicationWillResignActive:(UIApplication *)application
  20 +{
  21 + // 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.
  22 + // 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.
  23 +}
  24 +
  25 +- (void)applicationDidEnterBackground:(UIApplication *)application
  26 +{
  27 + // 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.
  28 + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
  29 +}
  30 +
  31 +- (void)applicationWillEnterForeground:(UIApplication *)application
  32 +{
  33 + // 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.
  34 +}
  35 +
  36 +- (void)applicationDidBecomeActive:(UIApplication *)application
  37 +{
  38 + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
  39 +}
  40 +
  41 +- (void)applicationWillTerminate:(UIApplication *)application
  42 +{
  43 + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
  44 +}
  45 +
  46 +@end
... ...
Example/CNLiveImagePickerController/CNLiveImagePickerController-Info.plist 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>en</string>
  7 + <key>CFBundleDisplayName</key>
  8 + <string>${PRODUCT_NAME}</string>
  9 + <key>CFBundleExecutable</key>
  10 + <string>${EXECUTABLE_NAME}</string>
  11 + <key>CFBundleIdentifier</key>
  12 + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
  13 + <key>CFBundleInfoDictionaryVersion</key>
  14 + <string>6.0</string>
  15 + <key>CFBundleName</key>
  16 + <string>${PRODUCT_NAME}</string>
  17 + <key>CFBundlePackageType</key>
  18 + <string>APPL</string>
  19 + <key>CFBundleShortVersionString</key>
  20 + <string>1.0</string>
  21 + <key>CFBundleSignature</key>
  22 + <string>????</string>
  23 + <key>CFBundleVersion</key>
  24 + <string>1.0</string>
  25 + <key>LSRequiresIPhoneOS</key>
  26 + <true/>
  27 + <key>UILaunchStoryboardName</key>
  28 + <string>LaunchScreen</string>
  29 + <key>UIMainStoryboardFile</key>
  30 + <string>Main</string>
  31 + <key>UIRequiredDeviceCapabilities</key>
  32 + <array>
  33 + <string>armv7</string>
  34 + </array>
  35 + <key>UISupportedInterfaceOrientations</key>
  36 + <array>
  37 + <string>UIInterfaceOrientationPortrait</string>
  38 + <string>UIInterfaceOrientationLandscapeLeft</string>
  39 + <string>UIInterfaceOrientationLandscapeRight</string>
  40 + </array>
  41 + <key>UISupportedInterfaceOrientations~ipad</key>
  42 + <array>
  43 + <string>UIInterfaceOrientationPortrait</string>
  44 + <string>UIInterfaceOrientationPortraitUpsideDown</string>
  45 + <string>UIInterfaceOrientationLandscapeLeft</string>
  46 + <string>UIInterfaceOrientationLandscapeRight</string>
  47 + </array>
  48 +</dict>
  49 +</plist>
... ...
Example/CNLiveImagePickerController/CNLiveImagePickerController-Prefix.pch 0 → 100644
  1 +//
  2 +// Prefix header
  3 +//
  4 +// The contents of this file are implicitly included at the beginning of every source file.
  5 +//
  6 +
  7 +#import <Availability.h>
  8 +
  9 +#ifndef __IPHONE_5_0
  10 +#warning "This project uses features only available in iOS SDK 5.0 and later."
  11 +#endif
  12 +
  13 +#ifdef __OBJC__
  14 + @import UIKit;
  15 + @import Foundation;
  16 +#endif
... ...
Example/CNLiveImagePickerController/CNLiveViewController.h 0 → 100644
  1 +//
  2 +// CNLiveViewController.h
  3 +// CNLiveImagePickerController
  4 +//
  5 +// Created by jyyjkt on 08/01/2019.
  6 +// Copyright (c) 2019 jyyjkt. All rights reserved.
  7 +//
  8 +
  9 +@import UIKit;
  10 +
  11 +@interface CNLiveViewController : UIViewController
  12 +
  13 +@end
... ...
Example/CNLiveImagePickerController/CNLiveViewController.m 0 → 100644
  1 +//
  2 +// CNLiveViewController.m
  3 +// CNLiveImagePickerController
  4 +//
  5 +// Created by jyyjkt on 08/01/2019.
  6 +// Copyright (c) 2019 jyyjkt. All rights reserved.
  7 +//
  8 +
  9 +#import "CNLiveViewController.h"
  10 +
  11 +@interface CNLiveViewController ()
  12 +
  13 +@end
  14 +
  15 +@implementation CNLiveViewController
  16 +
  17 +- (void)viewDidLoad
  18 +{
  19 + [super viewDidLoad];
  20 + // Do any additional setup after loading the view, typically from a nib.
  21 +}
  22 +
  23 +- (void)didReceiveMemoryWarning
  24 +{
  25 + [super didReceiveMemoryWarning];
  26 + // Dispose of any resources that can be recreated.
  27 +}
  28 +
  29 +@end
... ...
Example/CNLiveImagePickerController/Images.xcassets/AppIcon.appiconset/Contents.json 0 → 100644
  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 + "idiom" : "ipad",
  45 + "size" : "20x20",
  46 + "scale" : "1x"
  47 + },
  48 + {
  49 + "idiom" : "ipad",
  50 + "size" : "20x20",
  51 + "scale" : "2x"
  52 + },
  53 + {
  54 + "idiom" : "ipad",
  55 + "size" : "29x29",
  56 + "scale" : "1x"
  57 + },
  58 + {
  59 + "idiom" : "ipad",
  60 + "size" : "29x29",
  61 + "scale" : "2x"
  62 + },
  63 + {
  64 + "idiom" : "ipad",
  65 + "size" : "40x40",
  66 + "scale" : "1x"
  67 + },
  68 + {
  69 + "idiom" : "ipad",
  70 + "size" : "40x40",
  71 + "scale" : "2x"
  72 + },
  73 + {
  74 + "idiom" : "ipad",
  75 + "size" : "76x76",
  76 + "scale" : "1x"
  77 + },
  78 + {
  79 + "idiom" : "ipad",
  80 + "size" : "76x76",
  81 + "scale" : "2x"
  82 + },
  83 + {
  84 + "idiom" : "ipad",
  85 + "size" : "83.5x83.5",
  86 + "scale" : "2x"
  87 + },
  88 + {
  89 + "idiom" : "ios-marketing",
  90 + "size" : "1024x1024",
  91 + "scale" : "1x"
  92 + }
  93 + ],
  94 + "info" : {
  95 + "version" : 1,
  96 + "author" : "xcode"
  97 + }
  98 +}
... ...
Example/CNLiveImagePickerController/en.lproj/InfoPlist.strings 0 → 100644
  1 +/* Localized versions of Info.plist keys */
  2 +
... ...
Example/CNLiveImagePickerController/main.m 0 → 100644
  1 +//
  2 +// main.m
  3 +// CNLiveImagePickerController
  4 +//
  5 +// Created by jyyjkt on 08/01/2019.
  6 +// Copyright (c) 2019 jyyjkt. All rights reserved.
  7 +//
  8 +
  9 +@import UIKit;
  10 +#import "CNLiveAppDelegate.h"
  11 +
  12 +int main(int argc, char * argv[])
  13 +{
  14 + @autoreleasepool {
  15 + return UIApplicationMain(argc, argv, nil, NSStringFromClass([CNLiveAppDelegate class]));
  16 + }
  17 +}
... ...
Example/Podfile 0 → 100644
  1 +use_frameworks!
  2 +
  3 +platform :ios, '8.0'
  4 +
  5 +target 'CNLiveImagePickerController_Example' do
  6 + pod 'CNLiveImagePickerController', :path => '../'
  7 +
  8 + target 'CNLiveImagePickerController_Tests' do
  9 + inherit! :search_paths
  10 +
  11 +
  12 + end
  13 +end
... ...
Example/Tests/Tests-Info.plist 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>en</string>
  7 + <key>CFBundleExecutable</key>
  8 + <string>${EXECUTABLE_NAME}</string>
  9 + <key>CFBundleIdentifier</key>
  10 + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
  11 + <key>CFBundleInfoDictionaryVersion</key>
  12 + <string>6.0</string>
  13 + <key>CFBundlePackageType</key>
  14 + <string>BNDL</string>
  15 + <key>CFBundleShortVersionString</key>
  16 + <string>1.0</string>
  17 + <key>CFBundleSignature</key>
  18 + <string>????</string>
  19 + <key>CFBundleVersion</key>
  20 + <string>1</string>
  21 +</dict>
  22 +</plist>
... ...
Example/Tests/Tests-Prefix.pch 0 → 100644
  1 +// The contents of this file are implicitly included at the beginning of every test case source file.
  2 +
  3 +#ifdef __OBJC__
  4 +
  5 +
  6 +
  7 +#endif
... ...
Example/Tests/Tests.m 0 → 100644
  1 +//
  2 +// CNLiveImagePickerControllerTests.m
  3 +// CNLiveImagePickerControllerTests
  4 +//
  5 +// Created by jyyjkt on 08/01/2019.
  6 +// Copyright (c) 2019 jyyjkt. All rights reserved.
  7 +//
  8 +
  9 +@import XCTest;
  10 +
  11 +@interface Tests : XCTestCase
  12 +
  13 +@end
  14 +
  15 +@implementation Tests
  16 +
  17 +- (void)setUp
  18 +{
  19 + [super setUp];
  20 + // Put setup code here. This method is called before the invocation of each test method in the class.
  21 +}
  22 +
  23 +- (void)tearDown
  24 +{
  25 + // Put teardown code here. This method is called after the invocation of each test method in the class.
  26 + [super tearDown];
  27 +}
  28 +
  29 +- (void)testExample
  30 +{
  31 + XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
  32 +}
  33 +
  34 +@end
  35 +
... ...
Example/Tests/en.lproj/InfoPlist.strings 0 → 100644
  1 +/* Localized versions of Info.plist keys */
  2 +
... ...
1   -MIT License
2   -
3   -Copyright (c) 2018 cnlive
  1 +Copyright (c) 2019 jyyjkt <jyyjkt@qq.com>
4 2  
5 3 Permission is hereby granted, free of charge, to any person obtaining a copy
6 4 of this software and associated documentation files (the "Software"), to deal
... ... @@ -9,13 +7,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 7 copies of the Software, and to permit persons to whom the Software is
10 8 furnished to do so, subject to the following conditions:
11 9  
12   -The above copyright notice and this permission notice shall be included in all
13   -copies or substantial portions of the Software.
  10 +The above copyright notice and this permission notice shall be included in
  11 +all copies or substantial portions of the Software.
14 12  
15 13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 16 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 17 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20   -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21   -SOFTWARE.
22 18 \ No newline at end of file
  19 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20 +THE SOFTWARE.
... ...
README.md
  1 +# CNLiveImagePickerController
  2 +
  3 +[![CI Status](https://img.shields.io/travis/jyyjkt/CNLiveImagePickerController.svg?style=flat)](https://travis-ci.org/jyyjkt/CNLiveImagePickerController)
  4 +[![Version](https://img.shields.io/cocoapods/v/CNLiveImagePickerController.svg?style=flat)](https://cocoapods.org/pods/CNLiveImagePickerController)
  5 +[![License](https://img.shields.io/cocoapods/l/CNLiveImagePickerController.svg?style=flat)](https://cocoapods.org/pods/CNLiveImagePickerController)
  6 +[![Platform](https://img.shields.io/cocoapods/p/CNLiveImagePickerController.svg?style=flat)](https://cocoapods.org/pods/CNLiveImagePickerController)
  7 +
  8 +## Example
  9 +
  10 +To run the example project, clone the repo, and run `pod install` from the Example directory first.
  11 +
  12 +## Requirements
  13 +
  14 +## Installation
  15 +
  16 +CNLiveImagePickerController is available through [CocoaPods](https://cocoapods.org). To install
  17 +it, simply add the following line to your Podfile:
  18 +
  19 +```ruby
  20 +pod 'CNLiveImagePickerController'
  21 +```
  22 +
  23 +## Author
  24 +
  25 +jyyjkt, jyyjkt@qq.com
  26 +
  27 +## License
  28 +
  29 +CNLiveImagePickerController is available under the MIT license. See the LICENSE file for more info.
... ...
_Pods.xcodeproj 0 → 120000
  1 +Example/Pods/Pods.xcodeproj
0 2 \ No newline at end of file
... ...