Commit 2ad7fb49 authored by Syan's avatar Syan

0.1.7

parent dfa49399
......@@ -11,8 +11,8 @@
基于已有原生第三方框架封装的多图片选择组件,适用于 React Native App。
### 原生框架依赖
* Android: [PictureSelector 2.2.2](https://github.com/LuckSiege/PictureSelector) - by [LuckSiege](https://github.com/LuckSiege)
* iOS:[TZImagePickerController 2.0.0.4](https://github.com/banchichen/TZImagePickerController) - by [banchichen](https://github.com/banchichen)
* Android: [PictureSelector 2.2.3](https://github.com/LuckSiege/PictureSelector) - by [LuckSiege](https://github.com/LuckSiege)
* iOS:[TZImagePickerController 2.1.8](https://github.com/banchichen/TZImagePickerController) - by [banchichen](https://github.com/banchichen)
### 功能特点
* 支持 iOS、Android 两端
......
......@@ -13,7 +13,6 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 26
buildToolsVersion "26.0.3"
defaultConfig {
minSdkVersion 16
......@@ -32,5 +31,5 @@ repositories {
dependencies {
compile 'com.facebook.react:react-native:+'
compile 'com.github.LuckSiege.PictureSelector:picture_library:v2.2.2'
compile 'com.github.LuckSiege.PictureSelector:picture_library:v2.2.3'
}
......@@ -19,9 +19,10 @@ typedef enum : NSUInteger {
@class TZAssetModel;
@interface TZAssetCell : UICollectionViewCell
@property (weak, nonatomic) UIButton *selectPhotoButton;
@property (weak, nonatomic) UIButton *cannotSelectLayerButton;
@property (nonatomic, strong) TZAssetModel *model;
@property (assign, nonatomic) NSInteger index;
@property (nonatomic, copy) void (^didSelectPhotoBlock)(BOOL);
@property (nonatomic, assign) TZAssetCellType type;
@property (nonatomic, assign) BOOL allowPickingGif;
......@@ -29,27 +30,28 @@ typedef enum : NSUInteger {
@property (nonatomic, copy) NSString *representedAssetIdentifier;
@property (nonatomic, assign) int32_t imageRequestID;
@property (nonatomic, copy) NSString *photoSelImageName;
@property (nonatomic, copy) NSString *photoDefImageName;
@property (nonatomic, strong) UIImage *photoSelImage;
@property (nonatomic, strong) UIImage *photoDefImage;
@property (nonatomic, assign) BOOL showSelectBtn;
@property (assign, nonatomic) BOOL allowPreview;
@property (assign, nonatomic) BOOL useCachedImage;
@property (nonatomic, copy) void (^assetCellDidSetModelBlock)(TZAssetCell *cell, UIImageView *imageView, UIImageView *selectImageView, UILabel *indexLabel, UIView *bottomView, UILabel *timeLength, UIImageView *videoImgView);
@property (nonatomic, copy) void (^assetCellDidLayoutSubviewsBlock)(TZAssetCell *cell, UIImageView *imageView, UIImageView *selectImageView, UILabel *indexLabel, UIView *bottomView, UILabel *timeLength, UIImageView *videoImgView);
@end
@class TZAlbumModel;
@interface TZAlbumCell : UITableViewCell
@property (nonatomic, strong) TZAlbumModel *model;
@property (weak, nonatomic) UIButton *selectedCountButton;
@property (nonatomic, copy) void (^albumCellDidSetModelBlock)(TZAlbumCell *cell, UIImageView *posterImageView, UILabel *titleLabel);
@property (nonatomic, copy) void (^albumCellDidLayoutSubviewsBlock)(TZAlbumCell *cell, UIImageView *posterImageView, UILabel *titleLabel);
@end
@interface TZAssetCameraCell : UICollectionViewCell
@property (nonatomic, strong) UIImageView *imageView;
@end
......@@ -16,8 +16,10 @@
@interface TZAssetCell ()
@property (weak, nonatomic) UIImageView *imageView; // The photo / 照片
@property (weak, nonatomic) UIImageView *selectImageView;
@property (weak, nonatomic) UILabel *indexLabel;
@property (weak, nonatomic) UIView *bottomView;
@property (weak, nonatomic) UILabel *timeLength;
@property (strong, nonatomic) UITapGestureRecognizer *tapGesture;
@property (nonatomic, weak) UIImageView *videoImgView;
@property (nonatomic, strong) TZProgressView *progressView;
......@@ -31,22 +33,27 @@
if (iOS8Later) {
self.representedAssetIdentifier = [[TZImageManager manager] getAssetIdentifier:model.asset];
}
if (self.useCachedImage && model.cachedImage) {
self.imageView.image = model.cachedImage;
} else {
self.model.cachedImage = nil;
int32_t imageRequestID = [[TZImageManager manager] getPhotoWithAsset:model.asset photoWidth:self.tz_width completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
if (_progressView) {
self.progressView.hidden = YES;
self.imageView.alpha = 1.0;
}
// Set the cell's thumbnail image if it's still showing the same asset.
if (!iOS8Later) {
self.imageView.image = photo; return;
self.imageView.image = photo;
self.model.cachedImage = photo;
[self hideProgressView];
return;
}
if ([self.representedAssetIdentifier isEqualToString:[[TZImageManager manager] getAssetIdentifier:model.asset]]) {
self.imageView.image = photo;
self.model.cachedImage = photo;
} else {
// NSLog(@"this cell is showing other asset");
[[PHImageManager defaultManager] cancelImageRequest:self.imageRequestID];
}
if (!isDegraded) {
[self hideProgressView];
self.imageRequestID = 0;
}
} progressHandler:nil networkAccessAllowed:NO];
......@@ -55,8 +62,11 @@
// NSLog(@"cancelImageRequest %d",self.imageRequestID);
}
self.imageRequestID = imageRequestID;
}
self.selectPhotoButton.selected = model.isSelected;
self.selectImageView.image = self.selectPhotoButton.isSelected ? [UIImage imageNamedFromMyBundle:self.photoSelImageName] : [UIImage imageNamedFromMyBundle:self.photoDefImageName];
self.selectImageView.image = self.selectPhotoButton.isSelected ? self.photoSelImage : self.photoDefImage;
self.indexLabel.hidden = !self.selectPhotoButton.isSelected;
self.type = (NSInteger)model.type;
// 让宽度/高度小于 最小可选照片尺寸 的图片不能选中
if (![[TZImageManager manager] isPhotoSelectableWithAsset:model.asset]) {
......@@ -67,18 +77,35 @@
}
// 如果用户选中了该图片,提前获取一下大图
if (model.isSelected) {
[self fetchBigImage];
[self requestBigImage];
} else {
[self cancelBigImageRequest];
}
if (model.needOscillatoryAnimation) {
[UIView showOscillatoryAnimationWithLayer:self.selectImageView.layer type:TZOscillatoryAnimationToBigger];
}
model.needOscillatoryAnimation = NO;
[self setNeedsLayout];
if (self.assetCellDidSetModelBlock) {
self.assetCellDidSetModelBlock(self, _imageView, _selectImageView, _indexLabel, _bottomView, _timeLength, _videoImgView);
}
}
- (void)setIndex:(NSInteger)index {
_index = index;
self.indexLabel.text = [NSString stringWithFormat:@"%zd", index];
[self.contentView bringSubviewToFront:self.indexLabel];
}
- (void)setShowSelectBtn:(BOOL)showSelectBtn {
_showSelectBtn = showSelectBtn;
BOOL selectable = [[TZImageManager manager] isPhotoSelectableWithAsset:self.model.asset];
if (!self.selectPhotoButton.hidden) {
self.selectPhotoButton.hidden = !showSelectBtn;
self.selectPhotoButton.hidden = !showSelectBtn || !selectable;
}
if (!self.selectImageView.hidden) {
self.selectImageView.hidden = !showSelectBtn;
self.selectImageView.hidden = !showSelectBtn || !selectable;
}
}
......@@ -108,35 +135,56 @@
}
}
- (void)setAllowPreview:(BOOL)allowPreview {
_allowPreview = allowPreview;
if (allowPreview) {
_imageView.userInteractionEnabled = NO;
_tapGesture.enabled = NO;
} else {
_imageView.userInteractionEnabled = YES;
_tapGesture.enabled = YES;
}
}
- (void)selectPhotoButtonClick:(UIButton *)sender {
if (self.didSelectPhotoBlock) {
self.didSelectPhotoBlock(sender.isSelected);
}
self.selectImageView.image = sender.isSelected ? [UIImage imageNamedFromMyBundle:self.photoSelImageName] : [UIImage imageNamedFromMyBundle:self.photoDefImageName];
self.selectImageView.image = sender.isSelected ? self.photoSelImage : self.photoDefImage;
if (sender.isSelected) {
if (![TZImagePickerConfig sharedInstance].showSelectedIndex && ![TZImagePickerConfig sharedInstance].showPhotoCannotSelectLayer) {
[UIView showOscillatoryAnimationWithLayer:_selectImageView.layer type:TZOscillatoryAnimationToBigger];
}
// 用户选中了该图片,提前获取一下大图
[self fetchBigImage];
[self requestBigImage];
} else { // 取消选中,取消大图的获取
if (_bigImageRequestID && _progressView) {
[[PHImageManager defaultManager] cancelImageRequest:_bigImageRequestID];
[self hideProgressView];
[self cancelBigImageRequest];
}
}
/// 只在单选状态且allowPreview为NO时会有该事件
- (void)didTapImageView {
if (self.didSelectPhotoBlock) {
self.didSelectPhotoBlock(NO);
}
}
- (void)hideProgressView {
if (_progressView) {
self.progressView.hidden = YES;
self.imageView.alpha = 1.0;
}
}
- (void)fetchBigImage {
_bigImageRequestID = [[TZImageManager manager] getPhotoWithAsset:_model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
if (_progressView) {
[self hideProgressView];
- (void)requestBigImage {
if (_bigImageRequestID) {
[[PHImageManager defaultManager] cancelImageRequest:_bigImageRequestID];
}
_bigImageRequestID = [[TZImageManager manager] requestImageDataForAsset:_model.asset completion:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
[self hideProgressView];
} progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
if (_model.isSelected) {
if (self.model.isSelected) {
progress = progress > 0.02 ? progress : 0.02;;
self.progressView.progress = progress;
self.progressView.hidden = NO;
......@@ -147,14 +195,22 @@
} else {
*stop = YES;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[self cancelBigImageRequest];
}
} networkAccessAllowed:YES];
}];
}
- (void)cancelBigImageRequest {
if (_bigImageRequestID) {
[[PHImageManager defaultManager] cancelImageRequest:_bigImageRequestID];
}
[self hideProgressView];
}
#pragma mark - Lazy load
- (UIButton *)selectPhotoButton {
if (_selectImageView == nil) {
if (_selectPhotoButton == nil) {
UIButton *selectPhotoButton = [[UIButton alloc] init];
[selectPhotoButton addTarget:self action:@selector(selectPhotoButtonClick:) forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:selectPhotoButton];
......@@ -171,8 +227,8 @@
[self.contentView addSubview:imageView];
_imageView = imageView;
[self.contentView bringSubviewToFront:_selectImageView];
[self.contentView bringSubviewToFront:_bottomView];
_tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapImageView)];
[_imageView addGestureRecognizer:_tapGesture];
}
return _imageView;
}
......@@ -180,6 +236,8 @@
- (UIImageView *)selectImageView {
if (_selectImageView == nil) {
UIImageView *selectImageView = [[UIImageView alloc] init];
selectImageView.contentMode = UIViewContentModeCenter;
selectImageView.clipsToBounds = YES;
[self.contentView addSubview:selectImageView];
_selectImageView = selectImageView;
}
......@@ -197,6 +255,15 @@
return _bottomView;
}
- (UIButton *)cannotSelectLayerButton {
if (_cannotSelectLayerButton == nil) {
UIButton *cannotSelectLayerButton = [[UIButton alloc] init];
[self.contentView addSubview:cannotSelectLayerButton];
_cannotSelectLayerButton = cannotSelectLayerButton;
}
return _cannotSelectLayerButton;
}
- (UIImageView *)videoImgView {
if (_videoImgView == nil) {
UIImageView *videoImgView = [[UIImageView alloc] init];
......@@ -219,6 +286,18 @@
return _timeLength;
}
- (UILabel *)indexLabel {
if (_indexLabel == nil) {
UILabel *indexLabel = [[UILabel alloc] init];
indexLabel.font = [UIFont systemFontOfSize:14];
indexLabel.textColor = [UIColor whiteColor];
indexLabel.textAlignment = NSTextAlignmentCenter;
[self.contentView addSubview:indexLabel];
_indexLabel = indexLabel;
}
return _indexLabel;
}
- (TZProgressView *)progressView {
if (_progressView == nil) {
_progressView = [[TZProgressView alloc] init];
......@@ -230,12 +309,19 @@
- (void)layoutSubviews {
[super layoutSubviews];
_cannotSelectLayerButton.frame = self.bounds;
if (self.allowPreview) {
_selectPhotoButton.frame = CGRectMake(self.tz_width - 44, 0, 44, 44);
} else {
_selectPhotoButton.frame = self.bounds;
}
_selectImageView.frame = CGRectMake(self.tz_width - 27, 0, 27, 27);
_selectImageView.frame = CGRectMake(self.tz_width - 27, 3, 24, 24);
if (_selectImageView.image.size.width <= 27) {
_selectImageView.contentMode = UIViewContentModeCenter;
} else {
_selectImageView.contentMode = UIViewContentModeScaleAspectFit;
}
_indexLabel.frame = _selectImageView.frame;
_imageView.frame = CGRectMake(0, 0, self.tz_width, self.tz_height);
static CGFloat progressWH = 20;
......@@ -248,6 +334,16 @@
self.type = (NSInteger)self.model.type;
self.showSelectBtn = self.showSelectBtn;
[self.contentView bringSubviewToFront:_bottomView];
[self.contentView bringSubviewToFront:_cannotSelectLayerButton];
[self.contentView bringSubviewToFront:_selectPhotoButton];
[self.contentView bringSubviewToFront:_selectImageView];
[self.contentView bringSubviewToFront:_indexLabel];
if (self.assetCellDidLayoutSubviewsBlock) {
self.assetCellDidLayoutSubviewsBlock(self, _imageView, _selectImageView, _indexLabel, _bottomView, _timeLength, _videoImgView);
}
}
@end
......@@ -281,6 +377,10 @@
} else {
self.selectedCountButton.hidden = YES;
}
if (self.albumCellDidSetModelBlock) {
self.albumCellDidSetModelBlock(self, _posterImageView, _titleLabel);
}
}
/// For fitting iOS6
......@@ -290,6 +390,10 @@
NSInteger titleHeight = ceil(self.titleLabel.font.lineHeight);
self.titleLabel.frame = CGRectMake(80, (self.tz_height - titleHeight) / 2, self.tz_width - 80 - 50, titleHeight);
self.posterImageView.frame = CGRectMake(0, 0, 70, 70);
if (self.albumCellDidLayoutSubviewsBlock) {
self.albumCellDidLayoutSubviewsBlock(self, _posterImageView, _titleLabel);
}
}
- (void)layoutSublayersOfLayer:(CALayer *)layer {
......@@ -348,7 +452,7 @@
_imageView = [[UIImageView alloc] init];
_imageView.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.500];
_imageView.contentMode = UIViewContentModeScaleAspectFill;
[self addSubview:_imageView];
[self.contentView addSubview:_imageView];
self.clipsToBounds = YES;
}
return self;
......
......@@ -23,7 +23,9 @@ typedef enum : NSUInteger {
@property (nonatomic, strong) id asset; ///< PHAsset or ALAsset
@property (nonatomic, assign) BOOL isSelected; ///< The select status of a photo, default is No
@property (nonatomic, assign) TZAssetModelMediaType type;
@property (assign, nonatomic) BOOL needOscillatoryAnimation;
@property (nonatomic, copy) NSString *timeLength;
@property (strong, nonatomic) UIImage *cachedImage;
/// Init a photo dataModel With a asset
/// 用一个PHAsset/ALAsset实例,初始化一个照片模型
......
......@@ -35,8 +35,8 @@
_result = result;
if (needFetchAssets) {
[[TZImageManager manager] getAssetsFromFetchResult:result completion:^(NSArray<TZAssetModel *> *models) {
_models = models;
if (_selectedModels) {
self->_models = models;
if (self->_selectedModels) {
[self checkSelectedModels];
}
}];
......
......@@ -90,6 +90,10 @@
[_toolBar addSubview:byteLabel];
[self.view addSubview:_toolBar];
if (tzImagePickerVc.gifPreviewPageUIConfigBlock) {
tzImagePickerVc.gifPreviewPageUIConfigBlock(_toolBar, _doneButton);
}
}
#pragma mark - Layout
......@@ -102,6 +106,11 @@
CGFloat toolBarHeight = [TZCommonTools tz_isIPhoneX] ? 44 + (83 - 49) : 44;
_toolBar.frame = CGRectMake(0, self.view.tz_height - toolBarHeight, self.view.tz_width, toolBarHeight);
_doneButton.frame = CGRectMake(self.view.tz_width - 44 - 12, 0, 44, 44);
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (tzImagePickerVc.gifPreviewPageDidLayoutSubviewsBlock) {
tzImagePickerVc.gifPreviewPageDidLayoutSubviewsBlock(_toolBar, _doneButton);
}
}
#pragma mark - Click Event
......@@ -120,12 +129,14 @@
}
- (void)doneButtonClick {
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
if (self.navigationController) {
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
if (imagePickerVc.autoDismiss) {
[self.navigationController dismissViewControllerAnimated:YES completion:^{
[self callDelegateMethod];
}];
} else {
[self callDelegateMethod];
}
} else {
[self dismissViewControllerAnimated:YES completion:^{
......
......@@ -65,6 +65,7 @@
- (int32_t)getPhotoWithAsset:(id)asset photoWidth:(CGFloat)photoWidth completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
- (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;
- (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;
- (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;
/// Get full Image 获取原图
/// 如下两个方法completion一般会调多次,一般会先返回缩略图,再返回原图(详见方法内部使用的系统API的说明),如果info[PHImageResultIsDegradedKey] 为 YES,则表明当前返回的是缩略图,否则是原图。
......@@ -72,11 +73,16 @@
- (void)getOriginalPhotoWithAsset:(id)asset newCompletion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
// 该方法中,completion只会走一次
- (void)getOriginalPhotoDataWithAsset:(id)asset completion:(void (^)(NSData *data,NSDictionary *info,BOOL isDegraded))completion;
- (void)getOriginalPhotoDataWithAsset:(id)asset progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler completion:(void (^)(NSData *data,NSDictionary *info,BOOL isDegraded))completion;
/// Save photo 保存照片
- (void)savePhotoWithImage:(UIImage *)image completion:(void (^)(NSError *error))completion;
- (void)savePhotoWithImage:(UIImage *)image location:(CLLocation *)location completion:(void (^)(NSError *error))completion;
/// Save video 保存视频
- (void)saveVideoWithUrl:(NSURL *)url completion:(void (^)(NSError *error))completion;
- (void)saveVideoWithUrl:(NSURL *)url location:(CLLocation *)location completion:(void (^)(NSError *error))completion;
/// Get video 获得视频
- (void)getVideoWithAsset:(id)asset completion:(void (^)(AVPlayerItem * playerItem, NSDictionary * info))completion;
- (void)getVideoWithAsset:(id)asset progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler completion:(void (^)(AVPlayerItem *, NSDictionary *))completion;
......@@ -105,10 +111,12 @@
/// 获取asset的资源类型
- (TZAssetModelMediaType)getAssetType:(id)asset;
/// 缩放图片至新尺寸
- (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)size;
/// 判断asset是否是视频
- (BOOL)isVideo:(id)asset;
@end
//@interface TZSortDescriptor : NSSortDescriptor
......
......@@ -191,8 +191,8 @@ static dispatch_once_t onceToken;
}
}
if ([collection.localizedTitle tz_containsString:@"Hidden"] || [collection.localizedTitle isEqualToString:@"已隐藏"]) continue;
if ([collection.localizedTitle tz_containsString:@"Deleted"] || [collection.localizedTitle isEqualToString:@"最近删除"]) continue;
if (collection.assetCollectionSubtype == PHAssetCollectionSubtypeSmartAlbumAllHidden) continue;
if (collection.assetCollectionSubtype == 1000000201) continue; //『最近删除』相册
if ([self isCameraRollAlbum:collection]) {
[albumArr insertObject:[self modelWithResult:fetchResult name:collection.localizedTitle isCameraRoll:YES needFetchAssets:needFetchAssets] atIndex:0];
} else {
......@@ -217,7 +217,7 @@ static dispatch_once_t onceToken;
if ([self isCameraRollAlbum:group]) {
[albumArr insertObject:[self modelWithResult:group name:name isCameraRoll:YES needFetchAssets:needFetchAssets] atIndex:0];
} else if ([name isEqualToString:@"My Photo Stream"] || [name isEqualToString:@"我的照片流"]) {
} else if ([[group valueForProperty:ALAssetsGroupPropertyType] intValue] == ALAssetsGroupPhotoStream) {
if (albumArr.count) {
[albumArr insertObject:[self modelWithResult:group name:name isCameraRoll:NO needFetchAssets:needFetchAssets] atIndex:1];
} else {
......@@ -372,7 +372,7 @@ static dispatch_once_t onceToken;
if (phAsset.mediaType == PHAssetMediaTypeVideo) type = TZAssetModelMediaTypeVideo;
else if (phAsset.mediaType == PHAssetMediaTypeAudio) type = TZAssetModelMediaTypeAudio;
else if (phAsset.mediaType == PHAssetMediaTypeImage) {
if (iOS9_1Later) {
if (@available(iOS 9.1, *)) {
// if (asset.mediaSubtypes == PHAssetMediaSubtypePhotoLive) type = TZAssetModelMediaTypeLivePhoto;
}
// Gif
......@@ -419,6 +419,10 @@ static dispatch_once_t onceToken;
if ([model.asset isKindOfClass:[PHAsset class]]) {
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.resizeMode = PHImageRequestOptionsResizeModeFast;
options.networkAccessAllowed = YES;
if (model.type == TZAssetModelMediaTypePhotoGif) {
options.version = PHImageRequestOptionsVersionOriginal;
}
[[PHImageManager defaultManager] requestImageDataForAsset:model.asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
if (model.type != TZAssetModelMediaTypeVideo) dataLength += imageData.length;
assetCount ++;
......@@ -473,6 +477,36 @@ static dispatch_once_t onceToken;
return [self getPhotoWithAsset:asset photoWidth:fullScreenWidth completion:completion progressHandler:progressHandler networkAccessAllowed:networkAccessAllowed];
}
- (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 {
if ([asset isKindOfClass:[PHAsset class]]) {
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
dispatch_async(dispatch_get_main_queue(), ^{
if (progressHandler) {
progressHandler(progress, error, stop, info);
}
});
};
options.networkAccessAllowed = YES;
options.resizeMode = PHImageRequestOptionsResizeModeFast;
int32_t imageRequestID = [[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
if (completion) completion(imageData,dataUTI,orientation,info);
}];
return imageRequestID;
} else if ([asset isKindOfClass:[ALAsset class]]) {
ALAsset *alAsset = (ALAsset *)asset;
dispatch_async(dispatch_get_global_queue(0,0), ^{
ALAssetRepresentation *assetRep = [alAsset defaultRepresentation];
CGImageRef fullScrennImageRef = [assetRep fullScreenImage];
UIImage *fullScrennImage = [UIImage imageWithCGImage:fullScrennImageRef scale:2.0 orientation:UIImageOrientationUp];
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) completion(UIImageJPEGRepresentation(fullScrennImage, 0.83), nil, UIImageOrientationUp, nil);
});
});
}
return 0;
}
- (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 {
if ([asset isKindOfClass:[PHAsset class]]) {
CGSize imageSize;
......@@ -522,7 +556,9 @@ static dispatch_once_t onceToken;
options.resizeMode = PHImageRequestOptionsResizeModeFast;
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:options resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
UIImage *resultImage = [UIImage imageWithData:imageData scale:0.1];
if (![TZImagePickerConfig sharedInstance].notScaleImage) {
resultImage = [self scaleImage:resultImage toSize:imageSize];
}
if (!resultImage) {
resultImage = image;
}
......@@ -540,7 +576,7 @@ static dispatch_once_t onceToken;
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) completion(thumbnailImage,nil,YES);
if (photoWidth == TZScreenWidth || photoWidth == _photoPreviewMaxWidth) {
if (photoWidth == TZScreenWidth || photoWidth == self->_photoPreviewMaxWidth) {
dispatch_async(dispatch_get_global_queue(0,0), ^{
ALAssetRepresentation *assetRep = [alAsset defaultRepresentation];
CGImageRef fullScrennImageRef = [assetRep fullScreenImage];
......@@ -612,10 +648,18 @@ static dispatch_once_t onceToken;
}
- (void)getOriginalPhotoDataWithAsset:(id)asset completion:(void (^)(NSData *data,NSDictionary *info,BOOL isDegraded))completion {
[self getOriginalPhotoDataWithAsset:asset progressHandler:nil completion:completion];
}
- (void)getOriginalPhotoDataWithAsset:(id)asset progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler completion:(void (^)(NSData *data,NSDictionary *info,BOOL isDegraded))completion {
if ([asset isKindOfClass:[PHAsset class]]) {
PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
option.networkAccessAllowed = YES;
if ([[asset valueForKey:@"filename"] hasSuffix:@"GIF"]) {
// if version isn't PHImageRequestOptionsVersionOriginal, the gif may cann't play
option.version = PHImageRequestOptionsVersionOriginal;
}
[option setProgressHandler:progressHandler];
option.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
[[PHImageManager defaultManager] requestImageDataForAsset:asset options:option resultHandler:^(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info) {
BOOL downloadFinined = (![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey]);
......@@ -642,7 +686,7 @@ static dispatch_once_t onceToken;
- (void)savePhotoWithImage:(UIImage *)image location:(CLLocation *)location completion:(void (^)(NSError *error))completion {
if (iOS8Later) {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
if (iOS9Later) {
if (@available(iOS 9, *)) {
NSData *data = UIImageJPEGRepresentation(image, 0.9);
PHAssetResourceCreationOptions *options = [[PHAssetResourceCreationOptions alloc] init];
options.shouldMoveFile = YES;
......@@ -690,6 +734,61 @@ static dispatch_once_t onceToken;
}
}
#pragma mark - Save video
- (void)saveVideoWithUrl:(NSURL *)url completion:(void (^)(NSError *error))completion {
[self saveVideoWithUrl:url location:nil completion:completion];
}
- (void)saveVideoWithUrl:(NSURL *)url location:(CLLocation *)location completion:(void (^)(NSError *error))completion {
if (iOS8Later) {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
if (@available(iOS 9, *)) {
PHAssetResourceCreationOptions *options = [[PHAssetResourceCreationOptions alloc] init];
options.shouldMoveFile = YES;
PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAsset];
[request addResourceWithType:PHAssetResourceTypeVideo fileURL:url options:options];
if (location) {
request.location = location;
}
request.creationDate = [NSDate date];
} else {
PHAssetChangeRequest *request = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:url];
if (location) {
request.location = location;
}
request.creationDate = [NSDate date];
}
} completionHandler:^(BOOL success, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (success && completion) {
completion(nil);
} else if (error) {
NSLog(@"保存视频出错:%@",error.localizedDescription);
if (completion) {
completion(error);
}
}
});
}];
} else {
[self.assetLibrary writeVideoAtPathToSavedPhotosAlbum:url completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(@"保存视频出错:%@",error.localizedDescription);
if (completion) {
completion(error);
}
} else {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (completion) {
completion(nil);
}
});
}
}];
}
}
#pragma mark - Get Video
/// Get Video / 获取视频
......@@ -789,11 +888,13 @@ static dispatch_once_t onceToken;
[[NSFileManager defaultManager] createDirectoryAtPath:[NSHomeDirectory() stringByAppendingFormat:@"/tmp"] withIntermediateDirectories:YES attributes:nil error:nil];
}
if ([TZImagePickerConfig sharedInstance].needFixComposition) {
AVMutableVideoComposition *videoComposition = [self fixedCompositionWithAsset:videoAsset];
if (videoComposition.renderSize.width) {
// 修正视频转向
session.videoComposition = videoComposition;
}
}
// Begin to export video to the output path asynchronously.
[session exportAsynchronouslyWithCompletionHandler:^(void) {
......@@ -948,6 +1049,18 @@ static dispatch_once_t onceToken;
}
}
/// 判断asset是否是视频
- (BOOL)isVideo:(id)asset {
if (iOS8Later) {
PHAsset *phAsset = asset;
return phAsset.mediaType == PHAssetMediaTypeVideo;
} else {
ALAsset *alAsset = asset;
NSString *alAssetType = [[alAsset valueForProperty:ALAssetPropertyType] stringValue];
return [alAssetType isEqualToString:ALAssetTypeVideo];
}
}
- (ALAssetOrientation)orientationFromImage:(UIImage *)image {
NSInteger orientation = image.imageOrientation;
return orientation;
......
......@@ -4,7 +4,7 @@
//
// Created by 谭真 on 15/12/24.
// Copyright © 2015年 谭真. All rights reserved.
// version 2.0.0.9 - 2018.03.12
// version 2.2.6 - 2018.08.21
// 更多信息,请前往项目的github地址:https://github.com/banchichen/TZImagePickerController
/*
......@@ -19,12 +19,16 @@
#import <UIKit/UIKit.h>
#import "TZAssetModel.h"
#import "NSBundle+TZImagePicker.h"
#import "TZImageManager.h"
#import "TZVideoPlayerController.h"
#import "TZGifPhotoPreviewController.h"
#import "TZLocationManager.h"
#import "TZPhotoPreviewController.h"
#define iOS7Later ([UIDevice currentDevice].systemVersion.floatValue >= 7.0f)
#define iOS8Later ([UIDevice currentDevice].systemVersion.floatValue >= 8.0f)
#define iOS9Later ([UIDevice currentDevice].systemVersion.floatValue >= 9.0f)
#define iOS9_1Later ([UIDevice currentDevice].systemVersion.floatValue >= 9.1f)
@class TZAlbumCell, TZAssetCell;
@protocol TZImagePickerControllerDelegate;
@interface TZImagePickerController : UINavigationController
......@@ -71,7 +75,7 @@
/// Default is YES, if set NO, user can't picking video.
/// 默认为YES,如果设置为NO,用户将不能选择视频
@property (nonatomic, assign) BOOL allowPickingVideo;
/// Default is NO / 默认为NO,为YES时可以多选视频/gif图片,和照片共享最大可选张数maxImagesCount的限制
/// Default is NO / 默认为NO,为YES时可以多选视频/gif/图片,和照片共享最大可选张数maxImagesCount的限制
@property (nonatomic, assign) BOOL allowPickingMultipleVideo;
/// Default is NO, if set YES, user can picking gif image.
......@@ -80,11 +84,20 @@
/// Default is YES, if set NO, user can't picking image.
/// 默认为YES,如果设置为NO,用户将不能选择发送图片
@property(nonatomic, assign) BOOL allowPickingImage;
@property (nonatomic, assign) BOOL allowPickingImage;
/// Default is YES, if set NO, user can't take picture.
/// 默认为YES,如果设置为NO,拍照按钮将隐藏,用户将不能选择照片
@property(nonatomic, assign) BOOL allowTakePicture;
/// 默认为YES,如果设置为NO, 用户将不能拍摄照片
@property (nonatomic, assign) BOOL allowTakePicture;
@property (nonatomic, assign) BOOL allowCameraLocation;
/// Default is YES, if set NO, user can't take video.
/// 默认为YES,如果设置为NO, 用户将不能拍摄视频
@property(nonatomic, assign) BOOL allowTakeVideo;
/// Default value is 10 minutes / 视频最大拍摄时间,默认是10分钟,单位是秒
@property (assign, nonatomic) NSTimeInterval videoMaximumDuration;
/// Customizing UIImagePickerController's other properties, such as videoQuality / 定制UIImagePickerController的其它属性,比如视频拍摄质量videoQuality
@property (nonatomic, copy) void(^uiImagePickerControllerSettingBlock)(UIImagePickerController *imagePickerController);
/// 首选语言,如果设置了就用该语言,不设则取当前系统语言。
/// 由于目前只支持中文、繁体中文、英文、越南语。故该属性只支持zh-Hans、zh-Hant、en、vi四种值,其余值无效。
......@@ -102,14 +115,34 @@
/// 默认为YES,如果设置为NO, 选择器将不会自己dismiss
@property(nonatomic, assign) BOOL autoDismiss;
/// Default is YES, if set NO, in the delegate method the photos and infos will be nil, only assets hava value.
/// Default is NO, if set YES, in the delegate method the photos and infos will be nil, only assets hava value.
/// 默认为NO,如果设置为YES,代理方法里photos和infos会是nil,只返回assets
@property (assign, nonatomic) BOOL onlyReturnAsset;
/// Default is NO, if set YES, will show the image's selected index.
/// 默认为NO,如果设置为YES,会显示照片的选中序号
@property (assign, nonatomic) BOOL showSelectedIndex;
/// 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.
/// 默认是NO,如果设置为YES,当照片选择张数达到maxImagesCount时,其它照片会显示颜色为cannotSelectLayerColor的浮层
@property (assign, nonatomic) BOOL showPhotoCannotSelectLayer;
/// Default is white color with 0.8 alpha;
@property (strong, nonatomic) UIColor *cannotSelectLayerColor;
/// Default is No, if set YES, the result photo will not be scaled to photoWidth pixel width. The photoWidth default is 828px
/// 默认是NO,如果设置为YES,内部不会缩放图片到photoWidth像素宽
@property (assign, nonatomic) BOOL notScaleImage;
/// 默认是NO,如果设置为YES,导出视频时会修正转向(慎重设为YES,可能导致部分安卓下拍的视频导出失败)
@property (assign, nonatomic) BOOL needFixComposition;
/// The photos user have selected
/// 用户选中过的图片数组
@property (nonatomic, strong) NSMutableArray *selectedAssets;
@property (nonatomic, strong) NSMutableArray<TZAssetModel *> *selectedModels;
@property (nonatomic, strong) NSMutableArray *selectedAssetIds;
- (void)addSelectedModel:(TZAssetModel *)model;
- (void)removeSelectedModel:(TZAssetModel *)model;
/// Minimum selectable photo width, Default is 0
/// 最小可选中的图片宽度,默认是0,小于这个宽度的图片不可选中
......@@ -134,9 +167,23 @@
@property (nonatomic, assign) BOOL needCircleCrop; ///< 需要圆形裁剪框
@property (nonatomic, assign) NSInteger circleCropRadius; ///< 圆形裁剪框半径大小
@property (nonatomic, copy) void (^cropViewSettingBlock)(UIView *cropView); ///< 自定义裁剪框的其他属性
@property (nonatomic, copy) void (^navLeftBarButtonSettingBlock)(UIButton *leftButton); ///< 自定义返回按钮样式及其属性
/// 【自定义各页面/组件的样式】在界面初始化/组件setModel完成后调用,允许外界修改样式等
@property (nonatomic, copy) void (^photoPickerPageUIConfigBlock)(UICollectionView *collectionView, UIView *bottomToolBar, UIButton *previewButton, UIButton *originalPhotoButton, UILabel *originalPhotoLabel, UIButton *doneButton, UIImageView *numberImageView, UILabel *numberLabel, UIView *divideLine);
@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);
@property (nonatomic, copy) void (^videoPreviewPageUIConfigBlock)(UIButton *playButton, UIView *toolBar, UIButton *doneButton);
@property (nonatomic, copy) void (^gifPreviewPageUIConfigBlock)(UIView *toolBar, UIButton *doneButton);
@property (nonatomic, copy) void (^assetCellDidSetModelBlock)(TZAssetCell *cell, UIImageView *imageView, UIImageView *selectImageView, UILabel *indexLabel, UIView *bottomView, UILabel *timeLength, UIImageView *videoImgView);
@property (nonatomic, copy) void (^albumCellDidSetModelBlock)(TZAlbumCell *cell, UIImageView *posterImageView, UILabel *titleLabel);
/// 【自定义各页面/组件的frame】在界面viewDidLayoutSubviews/组件layoutSubviews后调用,允许外界修改frame等
@property (nonatomic, copy) void (^photoPickerPageDidLayoutSubviewsBlock)(UICollectionView *collectionView, UIView *bottomToolBar, UIButton *previewButton, UIButton *originalPhotoButton, UILabel *originalPhotoLabel, UIButton *doneButton, UIImageView *numberImageView, UILabel *numberLabel, UIView *divideLine);
@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);
@property (nonatomic, copy) void (^videoPreviewPageDidLayoutSubviewsBlock)(UIButton *playButton, UIView *toolBar, UIButton *doneButton);
@property (nonatomic, copy) void (^gifPreviewPageDidLayoutSubviewsBlock)(UIView *toolBar, UIButton *doneButton);
@property (nonatomic, copy) void (^assetCellDidLayoutSubviewsBlock)(TZAssetCell *cell, UIImageView *imageView, UIImageView *selectImageView, UILabel *indexLabel, UIView *bottomView, UILabel *timeLength, UIImageView *videoImgView);
@property (nonatomic, copy) void (^albumCellDidLayoutSubviewsBlock)(TZAlbumCell *cell, UIImageView *posterImageView, UILabel *titleLabel);
#pragma mark -
- (id)showAlertWithTitle:(NSString *)title;
- (void)hideAlertView:(id)alertView;
......@@ -146,13 +193,20 @@
@property (assign, nonatomic) BOOL needShowStatusBar;
#pragma mark -
@property (nonatomic, copy) NSString *takePictureImageName;
@property (nonatomic, copy) NSString *photoSelImageName;
@property (nonatomic, copy) NSString *photoDefImageName;
@property (nonatomic, copy) NSString *photoOriginSelImageName;
@property (nonatomic, copy) NSString *photoOriginDefImageName;
@property (nonatomic, copy) NSString *photoPreviewOriginDefImageName;
@property (nonatomic, copy) NSString *photoNumberIconImageName;
@property (nonatomic, copy) NSString *takePictureImageName __attribute__((deprecated("Use -takePictureImage.")));
@property (nonatomic, copy) NSString *photoSelImageName __attribute__((deprecated("Use -photoSelImage.")));
@property (nonatomic, copy) NSString *photoDefImageName __attribute__((deprecated("Use -photoDefImage.")));
@property (nonatomic, copy) NSString *photoOriginSelImageName __attribute__((deprecated("Use -photoOriginSelImage.")));
@property (nonatomic, copy) NSString *photoOriginDefImageName __attribute__((deprecated("Use -photoOriginDefImage.")));
@property (nonatomic, copy) NSString *photoPreviewOriginDefImageName __attribute__((deprecated("Use -photoPreviewOriginDefImage.")));
@property (nonatomic, copy) NSString *photoNumberIconImageName __attribute__((deprecated("Use -photoNumberIconImage.")));
@property (nonatomic, strong) UIImage *takePictureImage;
@property (nonatomic, strong) UIImage *photoSelImage;
@property (nonatomic, strong) UIImage *photoDefImage;
@property (nonatomic, strong) UIImage *photoOriginSelImage;
@property (nonatomic, strong) UIImage *photoOriginDefImage;
@property (nonatomic, strong) UIImage *photoPreviewOriginDefImage;
@property (nonatomic, strong) UIImage *photoNumberIconImage;
#pragma mark -
/// Appearance / 外观颜色 + 按钮文字
......@@ -171,6 +225,10 @@
@property (nonatomic, copy) NSString *settingBtnTitleStr;
@property (nonatomic, copy) NSString *processHintStr;
/// 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
/// icon主题色,默认是微信的绿色,值是r:31 g:185 b:34。目前仅支持showSelectedIndex为YES时的图片选中icon。如需要,请尽早设置它。
@property (strong, nonatomic) UIColor *iconThemeColor;
#pragma mark -
- (void)cancelButtonClick;
......@@ -274,4 +332,8 @@
@property (strong, nonatomic) NSBundle *languageBundle;
/// 默认是200,如果一个GIF过大,里面图片个数可能超过1000,会导致内存飙升而崩溃
@property (assign, nonatomic) NSInteger gifPreviewMaxImagesCount;
@property (assign, nonatomic) BOOL showSelectedIndex;
@property (assign, nonatomic) BOOL showPhotoCannotSelectLayer;
@property (assign, nonatomic) BOOL notScaleImage;
@property (assign, nonatomic) BOOL needFixComposition;
@end
......@@ -4,7 +4,7 @@
//
// Created by 谭真 on 15/12/24.
// Copyright © 2015年 谭真. All rights reserved.
// version 2.0.0.9 - 2018.03.12
// version 2.2.6 - 2018.08.21
// 更多信息,请前往项目的github地址:https://github.com/banchichen/TZImagePickerController
#import "TZImagePickerController.h"
......@@ -118,7 +118,7 @@
- (void)configBarButtonItemAppearance {
UIBarButtonItem *barItem;
if (iOS9Later) {
if (@available(iOS 9, *)) {
barItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[TZImagePickerController class]]];
} else {
barItem = [UIBarButtonItem appearanceWhenContainedIn:[TZImagePickerController class], nil];
......@@ -162,7 +162,7 @@
if (self) {
self.maxImagesCount = maxImagesCount > 0 ? maxImagesCount : 9; // Default is 9 / 默认最大可选9张图片
self.pickerDelegate = delegate;
self.selectedModels = [NSMutableArray array];
self.selectedAssets = [NSMutableArray array];
// Allow user picking original photo and video, you also can set No after this method
// 默认准许用户选择原图和视频, 你也可以在这个方法后置为NO
......@@ -170,6 +170,8 @@
self.allowPickingVideo = YES;
self.allowPickingImage = YES;
self.allowTakePicture = YES;
self.allowTakeVideo = YES;
self.videoMaximumDuration = 10 * 60;
self.sortAscendingByModificationDate = YES;
self.autoDismiss = YES;
self.columnNumber = columnNumber;
......@@ -269,9 +271,14 @@
self.barItemTextFont = [UIFont systemFontOfSize:15];
self.barItemTextColor = [UIColor whiteColor];
self.allowPreview = YES;
// 2.2.26版本,不主动缩放图片,降低内存占用
self.notScaleImage = YES;
self.needFixComposition = NO;
self.statusBarStyle = UIStatusBarStyleLightContent;
self.cannotSelectLayerColor = [[UIColor whiteColor] colorWithAlphaComponent:0.8];
self.allowCameraLocation = YES;
[self configDefaultImageName];
self.iconThemeColor = [UIColor colorWithRed:31 / 255.0 green:185 / 255.0 blue:34 / 255.0 alpha:1.0];
[self configDefaultBtnTitle];
CGFloat cropViewWH = MIN(self.view.tz_width, self.view.tz_height) / 3 * 2;
......@@ -279,15 +286,55 @@
}
- (void)configDefaultImageName {
self.takePictureImageName = @"takePicture";
self.takePictureImageName = @"takePicture80";
self.photoSelImageName = @"photo_sel_photoPickerVc";
self.photoDefImageName = @"photo_def_photoPickerVc";
self.photoNumberIconImageName = @"photo_number_icon";
self.photoNumberIconImage = [self createImageWithColor:nil size:CGSizeMake(24, 24) radius:12]; // @"photo_number_icon";
self.photoPreviewOriginDefImageName = @"preview_original_def";
self.photoOriginDefImageName = @"photo_original_def";
self.photoOriginSelImageName = @"photo_original_sel";
}
- (void)setTakePictureImageName:(NSString *)takePictureImageName {
_takePictureImageName = takePictureImageName;
_takePictureImage = [UIImage imageNamedFromMyBundle:takePictureImageName];
}
- (void)setPhotoSelImageName:(NSString *)photoSelImageName {
_photoSelImageName = photoSelImageName;
_photoSelImage = [UIImage imageNamedFromMyBundle:photoSelImageName];
}
- (void)setPhotoDefImageName:(NSString *)photoDefImageName {
_photoDefImageName = photoDefImageName;
_photoDefImage = [UIImage imageNamedFromMyBundle:photoDefImageName];
}
- (void)setPhotoNumberIconImageName:(NSString *)photoNumberIconImageName {
_photoNumberIconImageName = photoNumberIconImageName;
_photoNumberIconImage = [UIImage imageNamedFromMyBundle:photoNumberIconImageName];
}
- (void)setPhotoPreviewOriginDefImageName:(NSString *)photoPreviewOriginDefImageName {
_photoPreviewOriginDefImageName = photoPreviewOriginDefImageName;
_photoPreviewOriginDefImage = [UIImage imageNamedFromMyBundle:photoPreviewOriginDefImageName];
}
- (void)setPhotoOriginDefImageName:(NSString *)photoOriginDefImageName {
_photoOriginDefImageName = photoOriginDefImageName;
_photoOriginDefImage = [UIImage imageNamedFromMyBundle:photoOriginDefImageName];
}
- (void)setPhotoOriginSelImageName:(NSString *)photoOriginSelImageName {
_photoOriginSelImageName = photoOriginSelImageName;
_photoOriginSelImage = [UIImage imageNamedFromMyBundle:photoOriginSelImageName];
}
- (void)setIconThemeColor:(UIColor *)iconThemeColor {
_iconThemeColor = iconThemeColor;
[self configDefaultImageName];
}
- (void)configDefaultBtnTitle {
self.doneBtnTitleStr = [NSBundle tz_localizedStringForKey:@"Done"];
self.cancelBtnTitleStr = [NSBundle tz_localizedStringForKey:@"Cancel"];
......@@ -297,6 +344,29 @@
self.processHintStr = [NSBundle tz_localizedStringForKey:@"Processing..."];
}
- (void)setShowSelectedIndex:(BOOL)showSelectedIndex {
_showSelectedIndex = showSelectedIndex;
if (showSelectedIndex) {
self.photoSelImage = [self createImageWithColor:nil size:CGSizeMake(24, 24) radius:12];
}
[TZImagePickerConfig sharedInstance].showSelectedIndex = showSelectedIndex;
}
- (void)setShowPhotoCannotSelectLayer:(BOOL)showPhotoCannotSelectLayer {
_showPhotoCannotSelectLayer = showPhotoCannotSelectLayer;
[TZImagePickerConfig sharedInstance].showPhotoCannotSelectLayer = showPhotoCannotSelectLayer;
}
- (void)setNotScaleImage:(BOOL)notScaleImage {
_notScaleImage = notScaleImage;
[TZImagePickerConfig sharedInstance].notScaleImage = notScaleImage;
}
- (void)setNeedFixComposition:(BOOL)needFixComposition {
_needFixComposition = needFixComposition;
[TZImagePickerConfig sharedInstance].needFixComposition = needFixComposition;
}
- (void)observeAuthrizationStatusChange {
[_timer invalidate];
_timer = nil;
......@@ -327,7 +397,7 @@
[[TZImageManager manager] getCameraRollAlbum:self.allowPickingVideo allowPickingImage:self.allowPickingImage needFetchAssets:NO completion:^(TZAlbumModel *model) {
photoPickerVc.model = model;
[self pushViewController:photoPickerVc animated:YES];
_didPushPhotoPickerVc = YES;
self->_didPushPhotoPickerVc = YES;
}];
}
}
......@@ -493,21 +563,28 @@
- (void)setSelectedAssets:(NSMutableArray *)selectedAssets {
_selectedAssets = selectedAssets;
_selectedModels = [NSMutableArray array];
_selectedAssetIds = [NSMutableArray array];
for (id asset in selectedAssets) {
TZAssetModel *model = [TZAssetModel modelWithAsset:asset type:[[TZImageManager manager] getAssetType:asset]];
model.isSelected = YES;
[_selectedModels addObject:model];
[self addSelectedModel:model];
}
}
- (void)setAllowPickingImage:(BOOL)allowPickingImage {
_allowPickingImage = allowPickingImage;
[TZImagePickerConfig sharedInstance].allowPickingImage = allowPickingImage;
if (!allowPickingImage) {
_allowTakePicture = NO;
}
}
- (void)setAllowPickingVideo:(BOOL)allowPickingVideo {
_allowPickingVideo = allowPickingVideo;
[TZImagePickerConfig sharedInstance].allowPickingVideo = allowPickingVideo;
if (!allowPickingVideo) {
_allowTakeVideo = NO;
}
}
- (void)setPreferredLanguage:(NSString *)preferredLanguage {
......@@ -542,6 +619,34 @@
// NSLog(@"%@ dealloc",NSStringFromClass(self.class));
}
- (void)addSelectedModel:(TZAssetModel *)model {
[_selectedModels addObject:model];
NSString *assetId = [[TZImageManager manager] getAssetIdentifier:model.asset];
[_selectedAssetIds addObject:assetId];
}
- (void)removeSelectedModel:(TZAssetModel *)model {
[_selectedModels removeObject:model];
NSString *assetId = [[TZImageManager manager] getAssetIdentifier:model.asset];
[_selectedAssetIds removeObject:assetId];
}
- (UIImage *)createImageWithColor:(UIColor *)color size:(CGSize)size radius:(CGFloat)radius {
if (!color) {
color = self.iconThemeColor;
}
CGRect rect = CGRectMake(0.0f, 0.0f, size.width, size.height);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [color CGColor]);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius];
CGContextAddPath(context, path.CGPath);
CGContextFillPath(context);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
#pragma mark - UIContentContainer
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
......@@ -625,7 +730,7 @@
[super viewWillAppear:animated];
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
[imagePickerVc hideProgressHUD];
if (imagePickerVc.allowTakePicture) {
if (imagePickerVc.allowPickingImage) {
self.navigationItem.title = [NSBundle tz_localizedStringForKey:@"Photos"];
} else if (imagePickerVc.allowPickingVideo) {
self.navigationItem.title = [NSBundle tz_localizedStringForKey:@"Videos"];
......@@ -652,8 +757,8 @@
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
[[TZImageManager manager] getAllAlbums:imagePickerVc.allowPickingVideo allowPickingImage:imagePickerVc.allowPickingImage needFetchAssets:!self.isFirstAppear completion:^(NSArray<TZAlbumModel *> *models) {
dispatch_async(dispatch_get_main_queue(), ^{
_albumArr = [NSMutableArray arrayWithArray:models];
for (TZAlbumModel *albumModel in _albumArr) {
self->_albumArr = [NSMutableArray arrayWithArray:models];
for (TZAlbumModel *albumModel in self->_albumArr) {
albumModel.selectedModels = imagePickerVc.selectedModels;
}
[imagePickerVc hideProgressHUD];
......@@ -663,16 +768,16 @@
[self configTableView];
}
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_tableView.rowHeight = 70;
_tableView.tableFooterView = [[UIView alloc] init];
_tableView.dataSource = self;
_tableView.delegate = self;
[_tableView registerClass:[TZAlbumCell class] forCellReuseIdentifier:@"TZAlbumCell"];
[self.view addSubview:_tableView];
if (!self->_tableView) {
self->_tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
self->_tableView.rowHeight = 70;
self->_tableView.tableFooterView = [[UIView alloc] init];
self->_tableView.dataSource = self;
self->_tableView.delegate = self;
[self->_tableView registerClass:[TZAlbumCell class] forCellReuseIdentifier:@"TZAlbumCell"];
[self.view addSubview:self->_tableView];
} else {
[_tableView reloadData];
[self->_tableView reloadData];
}
});
}];
......@@ -711,7 +816,9 @@
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TZAlbumCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TZAlbumCell"];
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
cell.selectedCountButton.backgroundColor = imagePickerVc.oKButtonTitleColorNormal;
cell.albumCellDidLayoutSubviewsBlock = imagePickerVc.albumCellDidLayoutSubviewsBlock;
cell.albumCellDidSetModelBlock = imagePickerVc.albumCellDidSetModelBlock;
cell.selectedCountButton.backgroundColor = imagePickerVc.iconThemeColor;
cell.model = _albumArr[indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
......
......@@ -67,7 +67,7 @@
if (_geocodeBlock && locations.count) {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:[locations firstObject] completionHandler:^(NSArray *array, NSError *error) {
_geocodeBlock(array);
self->_geocodeBlock(array);
}];
}
}
......
......@@ -16,6 +16,7 @@
#import "TZVideoPlayerController.h"
#import "TZGifPhotoPreviewController.h"
#import "TZLocationManager.h"
#import <MobileCoreServices/MobileCoreServices.h>
@interface TZPhotoPickerController ()<UICollectionViewDataSource,UICollectionViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIAlertViewDelegate> {
NSMutableArray *_models;
......@@ -40,6 +41,7 @@
@property (strong, nonatomic) UICollectionViewFlowLayout *layout;
@property (nonatomic, strong) UIImagePickerController *imagePickerVc;
@property (strong, nonatomic) CLLocation *location;
@property (assign, nonatomic) BOOL useCachedImage;
@end
static CGSize AssetGridThumbnailSize;
......@@ -59,7 +61,7 @@ static CGFloat itemMargin = 5;
}
_imagePickerVc.navigationBar.tintColor = self.navigationController.navigationBar.tintColor;
UIBarButtonItem *tzBarItem, *BarItem;
if (iOS9Later) {
if (@available(iOS 9, *)) {
tzBarItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[TZImagePickerController class]]];
BarItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UIImagePickerController class]]];
} else {
......@@ -71,6 +73,7 @@ static CGFloat itemMargin = 5;
}
return _imagePickerVc;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.isFirstAppear = YES;
......@@ -86,8 +89,10 @@ static CGFloat itemMargin = 5;
[leftButton addTarget:self action:@selector(navLeftBarButtonClick) forControlEvents:UIControlEventTouchUpInside];
tzImagePickerVc.navLeftBarButtonSettingBlock(leftButton);
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:leftButton];
} else if (tzImagePickerVc.childViewControllers.count) {
[tzImagePickerVc.childViewControllers firstObject].navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:[NSBundle tz_localizedStringForKey:@"Back"] style:UIBarButtonItemStylePlain target:nil action:nil];
}
_showTakePhotoBtn = (_model.isCameraRoll && tzImagePickerVc.allowTakePicture);
_showTakePhotoBtn = _model.isCameraRoll && ((tzImagePickerVc.allowTakePicture && tzImagePickerVc.allowPickingImage) || (tzImagePickerVc.allowTakeVideo && tzImagePickerVc.allowPickingVideo));
// [self resetCachedAssets];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeStatusBarOrientationNotification:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
}
......@@ -98,20 +103,20 @@ static CGFloat itemMargin = 5;
[tzImagePickerVc showProgressHUD];
}
dispatch_async(dispatch_get_global_queue(0, 0), ^{
if (!tzImagePickerVc.sortAscendingByModificationDate && _isFirstAppear && iOS8Later && _model.isCameraRoll) {
if (!tzImagePickerVc.sortAscendingByModificationDate && self->_isFirstAppear && iOS8Later && self->_model.isCameraRoll) {
[[TZImageManager manager] getCameraRollAlbum:tzImagePickerVc.allowPickingVideo allowPickingImage:tzImagePickerVc.allowPickingImage needFetchAssets:YES completion:^(TZAlbumModel *model) {
_model = model;
_models = [NSMutableArray arrayWithArray:_model.models];
self->_model = model;
self->_models = [NSMutableArray arrayWithArray:self->_model.models];
[self initSubviews];
}];
} else {
if (_showTakePhotoBtn || !iOS8Later || _isFirstAppear) {
[[TZImageManager manager] getAssetsFromFetchResult:_model.result completion:^(NSArray<TZAssetModel *> *models) {
_models = [NSMutableArray arrayWithArray:models];
if (self->_showTakePhotoBtn || !iOS8Later || self->_isFirstAppear) {
[[TZImageManager manager] getAssetsFromFetchResult:self->_model.result completion:^(NSArray<TZAssetModel *> *models) {
self->_models = [NSMutableArray arrayWithArray:models];
[self initSubviews];
}];
} else {
_models = [NSMutableArray arrayWithArray:_model.models];
self->_models = [NSMutableArray arrayWithArray:self->_model.models];
[self initSubviews];
}
}
......@@ -125,7 +130,7 @@ static CGFloat itemMargin = 5;
[self checkSelectedModels];
[self configCollectionView];
_collectionView.hidden = YES;
self->_collectionView.hidden = YES;
[self configBottomToolBar];
[self scrollCollectionViewToBottom];
......@@ -143,8 +148,6 @@ static CGFloat itemMargin = 5;
}
- (void)configCollectionView {
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
_layout = [[UICollectionViewFlowLayout alloc] init];
_collectionView = [[TZCollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:_layout];
_collectionView.backgroundColor = [UIColor whiteColor];
......@@ -153,7 +156,7 @@ static CGFloat itemMargin = 5;
_collectionView.alwaysBounceHorizontal = NO;
_collectionView.contentInset = UIEdgeInsetsMake(itemMargin, itemMargin, itemMargin, itemMargin);
if (_showTakePhotoBtn && tzImagePickerVc.allowTakePicture ) {
if (_showTakePhotoBtn) {
_collectionView.contentSize = CGSizeMake(self.view.tz_width, ((_model.count + self.columnNumber) / self.columnNumber) * self.view.tz_width);
} else {
_collectionView.contentSize = CGSizeMake(self.view.tz_width, ((_model.count + self.columnNumber - 1) / self.columnNumber) * self.view.tz_width);
......@@ -211,8 +214,10 @@ static CGFloat itemMargin = 5;
[_originalPhotoButton setTitle:tzImagePickerVc.fullImageBtnTitleStr forState:UIControlStateSelected];
[_originalPhotoButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
[_originalPhotoButton setTitleColor:[UIColor blackColor] forState:UIControlStateSelected];
[_originalPhotoButton setImage:[UIImage imageNamedFromMyBundle:tzImagePickerVc.photoOriginDefImageName] forState:UIControlStateNormal];
[_originalPhotoButton setImage:[UIImage imageNamedFromMyBundle:tzImagePickerVc.photoOriginSelImageName] forState:UIControlStateSelected];
[_originalPhotoButton setImage:tzImagePickerVc.photoOriginDefImage forState:UIControlStateNormal];
[_originalPhotoButton setImage:tzImagePickerVc.photoOriginSelImage forState:UIControlStateSelected];
_originalPhotoButton.imageView.clipsToBounds = YES;
_originalPhotoButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
_originalPhotoButton.selected = _isSelectOriginalPhoto;
_originalPhotoButton.enabled = tzImagePickerVc.selectedModels.count > 0;
......@@ -232,8 +237,10 @@ static CGFloat itemMargin = 5;
[_doneButton setTitleColor:tzImagePickerVc.oKButtonTitleColorDisabled forState:UIControlStateDisabled];
_doneButton.enabled = tzImagePickerVc.selectedModels.count || tzImagePickerVc.alwaysEnableDoneBtn;
_numberImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamedFromMyBundle:tzImagePickerVc.photoNumberIconImageName]];
_numberImageView = [[UIImageView alloc] initWithImage:tzImagePickerVc.photoNumberIconImage];
_numberImageView.hidden = tzImagePickerVc.selectedModels.count <= 0;
_numberImageView.clipsToBounds = YES;
_numberImageView.contentMode = UIViewContentModeScaleAspectFit;
_numberImageView.backgroundColor = [UIColor clearColor];
_numberLabel = [[UILabel alloc] init];
......@@ -256,6 +263,10 @@ static CGFloat itemMargin = 5;
[_bottomToolBar addSubview:_originalPhotoButton];
[self.view addSubview:_bottomToolBar];
[_originalPhotoButton addSubview:_originalPhotoLabel];
if (tzImagePickerVc.photoPickerPageUIConfigBlock) {
tzImagePickerVc.photoPickerPageUIConfigBlock(_collectionView, _bottomToolBar, _previewButton, _originalPhotoButton, _originalPhotoLabel, _doneButton, _numberImageView, _numberLabel, _divideLine);
}
}
#pragma mark - Layout
......@@ -309,13 +320,17 @@ static CGFloat itemMargin = 5;
_originalPhotoLabel.frame = CGRectMake(fullImageWidth + 46, 0, 80, 50);
}
[_doneButton sizeToFit];
_doneButton.frame = CGRectMake(self.view.tz_width - _doneButton.tz_width - 12, 0, _doneButton.tz_width, toolBarHeight);
_numberImageView.frame = CGRectMake(_doneButton.tz_left - 30 - 2, (toolBarHeight - 30) / 2, 30, 30);
_doneButton.frame = CGRectMake(self.view.tz_width - _doneButton.tz_width - 12, 0, _doneButton.tz_width, 50);
_numberImageView.frame = CGRectMake(_doneButton.tz_left - 24 - 5, 13, 24, 24);
_numberLabel.frame = _numberImageView.frame;
_divideLine.frame = CGRectMake(0, 0, self.view.tz_width, 1);
[TZImageManager manager].columnNumber = [TZImageManager manager].columnNumber;
[self.collectionView reloadData];
if (tzImagePickerVc.photoPickerPageDidLayoutSubviewsBlock) {
tzImagePickerVc.photoPickerPageDidLayoutSubviewsBlock(_collectionView, _bottomToolBar, _previewButton, _originalPhotoButton, _originalPhotoLabel, _doneButton, _numberImageView, _numberLabel, _divideLine);
}
}
#pragma mark - Notification
......@@ -330,7 +345,7 @@ static CGFloat itemMargin = 5;
}
- (void)previewButtonClick {
TZPhotoPreviewController *photoPreviewVc = [[TZPhotoPreviewController alloc] init];
[self pushPhotoPrevireViewController:photoPreviewVc];
[self pushPhotoPrevireViewController:photoPreviewVc needCheckSelectedModels:YES];
}
- (void)originalPhotoButtonClick {
......@@ -373,7 +388,9 @@ static CGFloat itemMargin = 5;
[[TZImageManager manager] getPhotoWithAsset:model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
if (isDegraded) return;
if (photo) {
if (![TZImagePickerConfig sharedInstance].notScaleImage) {
photo = [[TZImageManager manager] scaleImage:photo toSize:CGSizeMake(tzImagePickerVc.photoWidth, (int)(tzImagePickerVc.photoWidth * photo.size.height / photo.size.width))];
}
[photos replaceObjectAtIndex:i withObject:photo];
}
if (info) [infoArr replaceObjectAtIndex:i withObject:info];
......@@ -419,6 +436,18 @@ static CGFloat itemMargin = 5;
- (void)callDelegateMethodWithPhotos:(NSArray *)photos assets:(NSArray *)assets infoArr:(NSArray *)infoArr {
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (tzImagePickerVc.allowPickingVideo && tzImagePickerVc.maxImagesCount == 1) {
if ([[TZImageManager manager] isVideo:[assets firstObject]]) {
if ([tzImagePickerVc.pickerDelegate respondsToSelector:@selector(imagePickerController:didFinishPickingVideo:sourceAssets:)]) {
[tzImagePickerVc.pickerDelegate imagePickerController:tzImagePickerVc didFinishPickingVideo:[photos firstObject] sourceAssets:[assets firstObject]];
}
if (tzImagePickerVc.didFinishPickingVideoHandle) {
tzImagePickerVc.didFinishPickingVideoHandle([photos firstObject], [assets firstObject]);
}
return;
}
}
if ([tzImagePickerVc.pickerDelegate respondsToSelector:@selector(imagePickerController:didFinishPickingPhotos:sourceAssets:isSelectOriginalPhoto:)]) {
[tzImagePickerVc.pickerDelegate imagePickerController:tzImagePickerVc didFinishPickingPhotos:photos sourceAssets:assets isSelectOriginalPhoto:_isSelectOriginalPhoto];
}
......@@ -437,38 +466,56 @@ static CGFloat itemMargin = 5;
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (_showTakePhotoBtn) {
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (tzImagePickerVc.allowPickingImage && tzImagePickerVc.allowTakePicture) {
return _models.count + 1;
}
}
return _models.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// the cell lead to take a picture / 去拍照的cell
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (((tzImagePickerVc.sortAscendingByModificationDate && indexPath.row >= _models.count) || (!tzImagePickerVc.sortAscendingByModificationDate && indexPath.row == 0)) && _showTakePhotoBtn) {
if (((tzImagePickerVc.sortAscendingByModificationDate && indexPath.item >= _models.count) || (!tzImagePickerVc.sortAscendingByModificationDate && indexPath.item == 0)) && _showTakePhotoBtn) {
TZAssetCameraCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TZAssetCameraCell" forIndexPath:indexPath];
cell.imageView.image = [UIImage imageNamedFromMyBundle:tzImagePickerVc.takePictureImageName];
cell.imageView.image = tzImagePickerVc.takePictureImage;
if ([tzImagePickerVc.takePictureImageName isEqualToString:@"takePicture80"]) {
cell.imageView.contentMode = UIViewContentModeCenter;
CGFloat rgb = 223 / 255.0;
cell.imageView.backgroundColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:1.0];
} else {
cell.imageView.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.500];
}
return cell;
}
// the cell dipaly photo or video / 展示照片或视频的cell
TZAssetCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TZAssetCell" forIndexPath:indexPath];
cell.allowPickingMultipleVideo = tzImagePickerVc.allowPickingMultipleVideo;
cell.photoDefImageName = tzImagePickerVc.photoDefImageName;
cell.photoSelImageName = tzImagePickerVc.photoSelImageName;
cell.photoDefImage = tzImagePickerVc.photoDefImage;
cell.photoSelImage = tzImagePickerVc.photoSelImage;
cell.useCachedImage = self.useCachedImage;
cell.assetCellDidSetModelBlock = tzImagePickerVc.assetCellDidSetModelBlock;
cell.assetCellDidLayoutSubviewsBlock = tzImagePickerVc.assetCellDidLayoutSubviewsBlock;
TZAssetModel *model;
if (tzImagePickerVc.sortAscendingByModificationDate || !_showTakePhotoBtn) {
model = _models[indexPath.row];
model = _models[indexPath.item];
} else {
model = _models[indexPath.row - 1];
model = _models[indexPath.item - 1];
}
cell.allowPickingGif = tzImagePickerVc.allowPickingGif;
cell.model = model;
if (model.isSelected && tzImagePickerVc.showSelectedIndex) {
NSString *assetId = [[TZImageManager manager] getAssetIdentifier:model.asset];
cell.index = [tzImagePickerVc.selectedAssetIds indexOfObject:assetId] + 1;
}
cell.showSelectBtn = tzImagePickerVc.showSelectBtn;
cell.allowPreview = tzImagePickerVc.allowPreview;
if (tzImagePickerVc.selectedModels.count >= tzImagePickerVc.maxImagesCount && tzImagePickerVc.showPhotoCannotSelectLayer && !model.isSelected) {
cell.cannotSelectLayerButton.backgroundColor = tzImagePickerVc.cannotSelectLayerColor;
cell.cannotSelectLayerButton.hidden = NO;
} else {
cell.cannotSelectLayerButton.hidden = YES;
}
__weak typeof(cell) weakCell = cell;
__weak typeof(self) weakSelf = self;
__weak typeof(_numberImageView.layer) weakLayer = _numberImageView.layer;
......@@ -484,24 +531,38 @@ static CGFloat itemMargin = 5;
NSArray *selectedModels = [NSArray arrayWithArray:tzImagePickerVc.selectedModels];
for (TZAssetModel *model_item in selectedModels) {
if ([[[TZImageManager manager] getAssetIdentifier:model.asset] isEqualToString:[[TZImageManager manager] getAssetIdentifier:model_item.asset]]) {
[tzImagePickerVc.selectedModels removeObject:model_item];
[tzImagePickerVc removeSelectedModel:model_item];
break;
}
}
[strongSelf refreshBottomToolBarStatus];
if (tzImagePickerVc.showSelectedIndex || tzImagePickerVc.showPhotoCannotSelectLayer) {
[strongSelf setUseCachedImageAndReloadData];
}
[UIView showOscillatoryAnimationWithLayer:strongLayer type:TZOscillatoryAnimationToSmaller];
} else {
// 2. select:check if over the maxImagesCount / 选择照片,检查是否超过了最大个数的限制
if (tzImagePickerVc.selectedModels.count < tzImagePickerVc.maxImagesCount) {
if (tzImagePickerVc.maxImagesCount == 1 && !tzImagePickerVc.allowPreview) {
model.isSelected = YES;
[tzImagePickerVc addSelectedModel:model];
[strongSelf doneButtonClick];
return;
}
strongCell.selectPhotoButton.selected = YES;
model.isSelected = YES;
[tzImagePickerVc.selectedModels addObject:model];
if (tzImagePickerVc.showSelectedIndex || tzImagePickerVc.showPhotoCannotSelectLayer) {
model.needOscillatoryAnimation = YES;
[strongSelf setUseCachedImageAndReloadData];
}
[tzImagePickerVc addSelectedModel:model];
[strongSelf refreshBottomToolBarStatus];
[UIView showOscillatoryAnimationWithLayer:strongLayer type:TZOscillatoryAnimationToSmaller];
} else {
NSString *title = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Select a maximum of %zd photos"], tzImagePickerVc.maxImagesCount];
[tzImagePickerVc showAlertWithTitle:title];
}
}
[UIView showOscillatoryAnimationWithLayer:strongLayer type:TZOscillatoryAnimationToSmaller];
};
return cell;
}
......@@ -509,13 +570,13 @@ static CGFloat itemMargin = 5;
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
// take a photo / 去拍照
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (((tzImagePickerVc.sortAscendingByModificationDate && indexPath.row >= _models.count) || (!tzImagePickerVc.sortAscendingByModificationDate && indexPath.row == 0)) && _showTakePhotoBtn) {
if (((tzImagePickerVc.sortAscendingByModificationDate && indexPath.item >= _models.count) || (!tzImagePickerVc.sortAscendingByModificationDate && indexPath.item == 0)) && _showTakePhotoBtn) {
[self takePhoto]; return;
}
// preview phote or video / 预览照片或视频
NSInteger index = indexPath.row;
NSInteger index = indexPath.item;
if (!tzImagePickerVc.sortAscendingByModificationDate && _showTakePhotoBtn) {
index = indexPath.row - 1;
index = indexPath.item - 1;
}
TZAssetModel *model = _models[index];
if (model.type == TZAssetModelMediaTypeVideo && !tzImagePickerVc.allowPickingMultipleVideo) {
......@@ -554,6 +615,14 @@ static CGFloat itemMargin = 5;
#pragma mark - Private Method
- (void)setUseCachedImageAndReloadData {
self.useCachedImage = YES;
[self.collectionView reloadData];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.useCachedImage = NO;
});
}
/// 拍照按钮点击事件
- (void)takePhoto {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
......@@ -593,6 +662,8 @@ static CGFloat itemMargin = 5;
// 调用相机
- (void)pushImagePickerController {
// 提前定位
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (tzImagePickerVc.allowCameraLocation) {
__weak typeof(self) weakSelf = self;
[[TZLocationManager manager] startLocationWithSuccessBlock:^(NSArray<CLLocation *> *locations) {
__strong typeof(weakSelf) strongSelf = weakSelf;
......@@ -601,13 +672,26 @@ static CGFloat itemMargin = 5;
__strong typeof(weakSelf) strongSelf = weakSelf;
strongSelf.location = nil;
}];
}
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) {
if ([UIImagePickerController isSourceTypeAvailable: sourceType]) {
self.imagePickerVc.sourceType = sourceType;
if(iOS8Later) {
NSMutableArray *mediaTypes = [NSMutableArray array];
if (tzImagePickerVc.allowTakePicture) {
[mediaTypes addObject:(NSString *)kUTTypeImage];
}
if (tzImagePickerVc.allowTakeVideo) {
[mediaTypes addObject:(NSString *)kUTTypeMovie];
self.imagePickerVc.videoMaximumDuration = tzImagePickerVc.videoMaximumDuration;
}
self.imagePickerVc.mediaTypes= mediaTypes;
if (iOS8Later) {
_imagePickerVc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
}
if (tzImagePickerVc.uiImagePickerControllerSettingBlock) {
tzImagePickerVc.uiImagePickerControllerSettingBlock(_imagePickerVc);
}
[self presentViewController:_imagePickerVc animated:YES completion:nil];
} else {
NSLog(@"模拟器中无法打开照相机,请在真机中使用");
......@@ -631,11 +715,18 @@ static CGFloat itemMargin = 5;
}
- (void)pushPhotoPrevireViewController:(TZPhotoPreviewController *)photoPreviewVc {
[self pushPhotoPrevireViewController:photoPreviewVc needCheckSelectedModels:NO];
}
- (void)pushPhotoPrevireViewController:(TZPhotoPreviewController *)photoPreviewVc needCheckSelectedModels:(BOOL)needCheckSelectedModels {
__weak typeof(self) weakSelf = self;
photoPreviewVc.isSelectOriginalPhoto = _isSelectOriginalPhoto;
[photoPreviewVc setBackButtonClickBlock:^(BOOL isSelectOriginalPhoto) {
__strong typeof(weakSelf) strongSelf = weakSelf;
strongSelf.isSelectOriginalPhoto = isSelectOriginalPhoto;
if (needCheckSelectedModels) {
[strongSelf checkSelectedModels];
}
[strongSelf.collectionView reloadData];
[strongSelf refreshBottomToolBarStatus];
}];
......@@ -658,7 +749,7 @@ static CGFloat itemMargin = 5;
}
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
[[TZImageManager manager] getPhotosBytesWithArray:imagePickerVc.selectedModels completion:^(NSString *totalBytes) {
_originalPhotoLabel.text = [NSString stringWithFormat:@"(%@)",totalBytes];
self->_originalPhotoLabel.text = [NSString stringWithFormat:@"(%@)",totalBytes];
}];
}
......@@ -669,16 +760,13 @@ static CGFloat itemMargin = 5;
if (tzImagePickerVc.sortAscendingByModificationDate) {
item = _models.count - 1;
if (_showTakePhotoBtn) {
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (tzImagePickerVc.allowPickingImage && tzImagePickerVc.allowTakePicture) {
item += 1;
}
}
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:item inSection:0] atScrollPosition:UICollectionViewScrollPositionBottom animated:NO];
_shouldScrollToBottom = NO;
_collectionView.hidden = NO;
[self->_collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:item inSection:0] atScrollPosition:UICollectionViewScrollPositionBottom animated:NO];
self->_shouldScrollToBottom = NO;
self->_collectionView.hidden = NO;
});
} else {
_collectionView.hidden = NO;
......@@ -721,7 +809,19 @@ static CGFloat itemMargin = 5;
if (photo) {
[[TZImageManager manager] savePhotoWithImage:photo location:self.location completion:^(NSError *error){
if (!error) {
[self reloadPhotoArray];
[self reloadPhotoArrayWithMediaType:type];
}
}];
self.location = nil;
}
} else if ([type isEqualToString:@"public.movie"]) {
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
[imagePickerVc showProgressHUD];
NSURL *videoUrl = [info objectForKey:UIImagePickerControllerMediaURL];
if (videoUrl) {
[[TZImageManager manager] saveVideoWithUrl:videoUrl location:self.location completion:^(NSError *error) {
if (!error) {
[self reloadPhotoArrayWithMediaType:type];
}
}];
self.location = nil;
......@@ -729,48 +829,52 @@ static CGFloat itemMargin = 5;
}
}
- (void)reloadPhotoArray {
- (void)reloadPhotoArrayWithMediaType:(NSString *)mediaType {
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
[[TZImageManager manager] getCameraRollAlbum:tzImagePickerVc.allowPickingVideo allowPickingImage:tzImagePickerVc.allowPickingImage needFetchAssets:NO completion:^(TZAlbumModel *model) {
_model = model;
[[TZImageManager manager] getAssetsFromFetchResult:_model.result completion:^(NSArray<TZAssetModel *> *models) {
self->_model = model;
[[TZImageManager manager] getAssetsFromFetchResult:self->_model.result completion:^(NSArray<TZAssetModel *> *models) {
[tzImagePickerVc hideProgressHUD];
TZAssetModel *assetModel;
if (tzImagePickerVc.sortAscendingByModificationDate) {
assetModel = [models lastObject];
[_models addObject:assetModel];
[self->_models addObject:assetModel];
} else {
assetModel = [models firstObject];
[_models insertObject:assetModel atIndex:0];
[self->_models insertObject:assetModel atIndex:0];
}
if (tzImagePickerVc.maxImagesCount <= 1) {
if (tzImagePickerVc.allowCrop) {
TZPhotoPreviewController *photoPreviewVc = [[TZPhotoPreviewController alloc] init];
if (tzImagePickerVc.sortAscendingByModificationDate) {
photoPreviewVc.currentIndex = _models.count - 1;
photoPreviewVc.currentIndex = self->_models.count - 1;
} else {
photoPreviewVc.currentIndex = 0;
}
photoPreviewVc.models = _models;
photoPreviewVc.models = self->_models;
[self pushPhotoPrevireViewController:photoPreviewVc];
} else {
[tzImagePickerVc.selectedModels addObject:assetModel];
[tzImagePickerVc addSelectedModel:assetModel];
[self doneButtonClick];
}
return;
}
if (tzImagePickerVc.selectedModels.count < tzImagePickerVc.maxImagesCount) {
if ([mediaType isEqualToString:@"public.movie"] && !tzImagePickerVc.allowPickingMultipleVideo) {
// 不能多选视频的情况下,不选中拍摄的视频
} else {
assetModel.isSelected = YES;
[tzImagePickerVc.selectedModels addObject:assetModel];
[tzImagePickerVc addSelectedModel:assetModel];
[self refreshBottomToolBarStatus];
}
_collectionView.hidden = YES;
[_collectionView reloadData];
}
self->_collectionView.hidden = YES;
[self->_collectionView reloadData];
_shouldScrollToBottom = YES;
self->_shouldScrollToBottom = YES;
[self scrollCollectionViewToBottom];
}];
}];
......
......@@ -92,7 +92,7 @@
@interface TZPhotoPreviewView ()<UIScrollViewDelegate>
@property (assign, nonatomic) BOOL isRequestingGIF;
@end
@implementation TZPhotoPreviewView
......@@ -113,6 +113,9 @@
_scrollView.delaysContentTouches = NO;
_scrollView.canCancelContentTouches = YES;
_scrollView.alwaysBounceVertical = NO;
if (@available(iOS 11, *)) {
_scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}
[self addSubview:_scrollView];
_imageContainerView = [[UIView alloc] init];
......@@ -146,15 +149,35 @@
- (void)setModel:(TZAssetModel *)model {
_model = model;
self.isRequestingGIF = NO;
[_scrollView setZoomScale:1.0 animated:NO];
if (model.type == TZAssetModelMediaTypePhotoGif) {
// 先显示缩略图
[[TZImageManager manager] getPhotoWithAsset:model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
self.imageView.image = photo;
[self resizeSubviews];
if (self.isRequestingGIF) {
return;
}
// 再显示gif动图
[[TZImageManager manager] getOriginalPhotoDataWithAsset:model.asset completion:^(NSData *data, NSDictionary *info, BOOL isDegraded) {
self.isRequestingGIF = YES;
[[TZImageManager manager] getOriginalPhotoDataWithAsset:model.asset progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
progress = progress > 0.02 ? progress : 0.02;
dispatch_async(dispatch_get_main_queue(), ^{
self.progressView.progress = progress;
if (progress >= 1) {
self.progressView.hidden = YES;
} else {
self.progressView.hidden = NO;
}
});
#ifdef DEBUG
NSLog(@"[TZImagePickerController] getOriginalPhotoDataWithAsset:%f error:%@", progress, error);
#endif
} completion:^(NSData *data, NSDictionary *info, BOOL isDegraded) {
if (!isDegraded) {
self.isRequestingGIF = NO;
self.progressView.hidden = YES;
self.imageView.image = [UIImage sd_tz_animatedGIFWithData:data];
[self resizeSubviews];
}
......@@ -172,10 +195,10 @@
_asset = asset;
self.imageRequestID = [[TZImageManager manager] getPhotoWithAsset:asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
if (![asset isEqual:_asset]) return;
if (![asset isEqual:self->_asset]) return;
self.imageView.image = photo;
[self resizeSubviews];
_progressView.hidden = YES;
self->_progressView.hidden = YES;
if (self.imageProgressUpdateBlock) {
self.imageProgressUpdateBlock(1);
}
......@@ -183,17 +206,17 @@
self.imageRequestID = 0;
}
} progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
if (![asset isEqual:_asset]) return;
_progressView.hidden = NO;
[self bringSubviewToFront:_progressView];
if (![asset isEqual:self->_asset]) return;
self->_progressView.hidden = NO;
[self bringSubviewToFront:self->_progressView];
progress = progress > 0.02 ? progress : 0.02;
_progressView.progress = progress;
self->_progressView.progress = progress;
if (self.imageProgressUpdateBlock && progress < 1) {
self.imageProgressUpdateBlock(progress);
}
if (progress >= 1) {
_progressView.hidden = YES;
self->_progressView.hidden = YES;
self.imageRequestID = 0;
}
} networkAccessAllowed:YES];
......@@ -355,17 +378,17 @@
}
[[TZImageManager manager] getPhotoWithAsset:self.model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
_cover = photo;
self->_cover = photo;
}];
[[TZImageManager manager] getVideoWithAsset:self.model.asset completion:^(AVPlayerItem *playerItem, NSDictionary *info) {
dispatch_async(dispatch_get_main_queue(), ^{
_player = [AVPlayer playerWithPlayerItem:playerItem];
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
_playerLayer.backgroundColor = [UIColor blackColor].CGColor;
_playerLayer.frame = self.bounds;
[self.layer addSublayer:_playerLayer];
self->_player = [AVPlayer playerWithPlayerItem:playerItem];
self->_playerLayer = [AVPlayerLayer playerLayerWithPlayer:self->_player];
self->_playerLayer.backgroundColor = [UIColor blackColor].CGColor;
self->_playerLayer.frame = self.bounds;
[self.layer addSublayer:self->_playerLayer];
[self configPlayButton];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pausePlayerAndShowNaviBar) name:AVPlayerItemDidPlayToEndTimeNotification object:_player.currentItem];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pausePlayerAndShowNaviBar) name:AVPlayerItemDidPlayToEndTimeNotification object:self->_player.currentItem];
});
}];
}
......
......@@ -23,6 +23,7 @@
UIView *_naviBar;
UIButton *_backButton;
UIButton *_selectButton;
UILabel *_indexLabel;
UIView *_toolBar;
UIButton *_doneButton;
......@@ -32,6 +33,8 @@
UILabel *_originalPhotoLabel;
CGFloat _offsetItemCount;
BOOL _didSetIsSelectOriginalPhoto;
}
@property (nonatomic, assign) BOOL isHideNaviBar;
@property (nonatomic, strong) UIView *cropBgView;
......@@ -46,8 +49,10 @@
- (void)viewDidLoad {
[super viewDidLoad];
[TZImageManager manager].shouldFixOrientation = YES;
__weak typeof(self) weakSelf = self;
TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)weakSelf.navigationController;
TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (!_didSetIsSelectOriginalPhoto) {
_isSelectOriginalPhoto = _tzImagePickerVc.isSelectOriginalPhoto;
}
if (!self.models.count) {
self.models = [NSMutableArray arrayWithArray:_tzImagePickerVc.selectedModels];
_assetsTemp = [NSMutableArray arrayWithArray:_tzImagePickerVc.selectedAssets];
......@@ -59,6 +64,11 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeStatusBarOrientationNotification:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
}
- (void)setIsSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto {
_isSelectOriginalPhoto = isSelectOriginalPhoto;
_didSetIsSelectOriginalPhoto = YES;
}
- (void)setPhotos:(NSMutableArray *)photos {
_photos = photos;
_photosTemp = [NSArray arrayWithArray:photos];
......@@ -98,12 +108,21 @@
[_backButton addTarget:self action:@selector(backButtonClick) forControlEvents:UIControlEventTouchUpInside];
_selectButton = [[UIButton alloc] initWithFrame:CGRectZero];
[_selectButton setImage:[UIImage imageNamedFromMyBundle:tzImagePickerVc.photoDefImageName] forState:UIControlStateNormal];
[_selectButton setImage:[UIImage imageNamedFromMyBundle:tzImagePickerVc.photoSelImageName] forState:UIControlStateSelected];
[_selectButton setImage:tzImagePickerVc.photoDefImage forState:UIControlStateNormal];
[_selectButton setImage:tzImagePickerVc.photoSelImage forState:UIControlStateSelected];
_selectButton.imageView.clipsToBounds = YES;
_selectButton.imageEdgeInsets = UIEdgeInsetsMake(10, 0, 10, 0);
_selectButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
[_selectButton addTarget:self action:@selector(select:) forControlEvents:UIControlEventTouchUpInside];
_selectButton.hidden = !tzImagePickerVc.showSelectBtn;
_indexLabel = [[UILabel alloc] init];
_indexLabel.font = [UIFont systemFontOfSize:14];
_indexLabel.textColor = [UIColor whiteColor];
_indexLabel.textAlignment = NSTextAlignmentCenter;
[_naviBar addSubview:_selectButton];
[_naviBar addSubview:_indexLabel];
[_naviBar addSubview:_backButton];
[self.view addSubview:_naviBar];
}
......@@ -124,8 +143,8 @@
[_originalPhotoButton setTitle:_tzImagePickerVc.fullImageBtnTitleStr forState:UIControlStateSelected];
[_originalPhotoButton setTitleColor:[UIColor lightGrayColor] forState:UIControlStateNormal];
[_originalPhotoButton setTitleColor:[UIColor whiteColor] forState:UIControlStateSelected];
[_originalPhotoButton setImage:[UIImage imageNamedFromMyBundle:_tzImagePickerVc.photoPreviewOriginDefImageName] forState:UIControlStateNormal];
[_originalPhotoButton setImage:[UIImage imageNamedFromMyBundle:_tzImagePickerVc.photoOriginSelImageName] forState:UIControlStateSelected];
[_originalPhotoButton setImage:_tzImagePickerVc.photoPreviewOriginDefImage forState:UIControlStateNormal];
[_originalPhotoButton setImage:_tzImagePickerVc.photoOriginSelImage forState:UIControlStateSelected];
_originalPhotoLabel = [[UILabel alloc] init];
_originalPhotoLabel.textAlignment = NSTextAlignmentLeft;
......@@ -141,8 +160,10 @@
[_doneButton setTitle:_tzImagePickerVc.doneBtnTitleStr forState:UIControlStateNormal];
[_doneButton setTitleColor:_tzImagePickerVc.oKButtonTitleColorNormal forState:UIControlStateNormal];
_numberImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamedFromMyBundle:_tzImagePickerVc.photoNumberIconImageName]];
_numberImageView = [[UIImageView alloc] initWithImage:_tzImagePickerVc.photoNumberIconImage];
_numberImageView.backgroundColor = [UIColor clearColor];
_numberImageView.clipsToBounds = YES;
_numberImageView.contentMode = UIViewContentModeScaleAspectFit;
_numberImageView.hidden = _tzImagePickerVc.selectedModels.count <= 0;
_numberLabel = [[UILabel alloc] init];
......@@ -159,6 +180,10 @@
[_toolBar addSubview:_numberImageView];
[_toolBar addSubview:_numberLabel];
[self.view addSubview:_toolBar];
if (_tzImagePickerVc.photoPreviewPageUIConfigBlock) {
_tzImagePickerVc.photoPreviewPageUIConfigBlock(_collectionView, _naviBar, _backButton, _selectButton, _indexLabel, _toolBar, _originalPhotoButton, _originalPhotoLabel, _doneButton, _numberImageView, _numberLabel);
}
}
- (void)configCollectionView {
......@@ -223,7 +248,8 @@
CGFloat naviBarHeight = statusBarHeight + _tzImagePickerVc.navigationBar.tz_height;
_naviBar.frame = CGRectMake(0, 0, self.view.tz_width, naviBarHeight);
_backButton.frame = CGRectMake(10, 10 + statusBarHeightInterval, 44, 44);
_selectButton.frame = CGRectMake(self.view.tz_width - 54, 10 + statusBarHeightInterval, 42, 42);
_selectButton.frame = CGRectMake(self.view.tz_width - 56, 10 + statusBarHeightInterval, 44, 44);
_indexLabel.frame = _selectButton.frame;
_layout.itemSize = CGSizeMake(self.view.tz_width + 20, self.view.tz_height);
_layout.minimumInteritemSpacing = 0;
......@@ -247,11 +273,15 @@
_originalPhotoLabel.frame = CGRectMake(fullImageWidth + 42, 0, 80, 44);
}
[_doneButton sizeToFit];
_doneButton.frame = CGRectMake(self.view.tz_width - _doneButton.tz_width - 12, 0, _doneButton.tz_width, toolBarHeight);
_numberImageView.frame = CGRectMake(_doneButton.tz_left - 30 - 2, (toolBarHeight - 30) / 2, 30, 30);
_doneButton.frame = CGRectMake(self.view.tz_width - _doneButton.tz_width - 12, 0, _doneButton.tz_width, 44);
_numberImageView.frame = CGRectMake(_doneButton.tz_left - 24 - 5, 10, 24, 24);
_numberLabel.frame = _numberImageView.frame;
[self configCropView];
if (_tzImagePickerVc.photoPreviewPageDidLayoutSubviewsBlock) {
_tzImagePickerVc.photoPreviewPageDidLayoutSubviewsBlock(_collectionView, _naviBar, _backButton, _selectButton, _indexLabel, _toolBar, _originalPhotoButton, _originalPhotoLabel, _doneButton, _numberImageView, _numberLabel);
}
}
#pragma mark - Notification
......@@ -273,7 +303,7 @@
return;
// 2. if not over the maxImagesCount / 如果没有超过最大个数限制
} else {
[_tzImagePickerVc.selectedModels addObject:model];
[_tzImagePickerVc addSelectedModel:model];
if (self.photos) {
[_tzImagePickerVc.selectedAssets addObject:_assetsTemp[_currentIndex]];
[self.photos addObject:_photosTemp[_currentIndex]];
......@@ -291,11 +321,11 @@
for (NSInteger i = 0; i < selectedModelsTmp.count; i++) {
TZAssetModel *model = selectedModelsTmp[i];
if ([model isEqual:model_item]) {
[_tzImagePickerVc.selectedModels removeObjectAtIndex:i];
[_tzImagePickerVc removeSelectedModel:model];
// [_tzImagePickerVc.selectedModels removeObjectAtIndex:i];
break;
}
}
// [_tzImagePickerVc.selectedModels removeObject:model_item];
if (self.photos) {
// 1.6.7版本更新:防止有多个一样的asset,一次性被移除了
NSArray *selectedAssetsTmp = [NSArray arrayWithArray:_tzImagePickerVc.selectedAssets];
......@@ -324,6 +354,12 @@
- (void)backButtonClick {
if (self.navigationController.childViewControllers.count < 2) {
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
if ([self.navigationController isKindOfClass: [TZImagePickerController class]]) {
TZImagePickerController *nav = (TZImagePickerController *)self.navigationController;
if (nav.imagePickerControllerDidCancelHandle) {
nav.imagePickerControllerDidCancelHandle();
}
}
return;
}
[self.navigationController popViewControllerAnimated:YES];
......@@ -343,7 +379,7 @@
// 如果没有选中过照片 点击确定时选中当前预览的照片
if (_tzImagePickerVc.selectedModels.count == 0 && _tzImagePickerVc.minImagesCount <= 0) {
TZAssetModel *model = _models[_currentIndex];
[_tzImagePickerVc.selectedModels addObject:model];
[_tzImagePickerVc addSelectedModel:model];
}
if (_tzImagePickerVc.allowCrop) { // 裁剪状态
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:_currentIndex inSection:0];
......@@ -410,7 +446,7 @@
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
TZAssetModel *model = _models[indexPath.row];
TZAssetModel *model = _models[indexPath.item];
TZAssetPreviewCell *cell;
__weak typeof(self) weakSelf = self;
......@@ -475,6 +511,15 @@
TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
TZAssetModel *model = _models[_currentIndex];
_selectButton.selected = model.isSelected;
[self refreshSelectButtonImageViewContentMode];
if (_selectButton.isSelected && _tzImagePickerVc.showSelectedIndex && _tzImagePickerVc.showSelectBtn) {
NSString *assetId = [[TZImageManager manager] getAssetIdentifier:model.asset];
NSString *index = [NSString stringWithFormat:@"%zd", [_tzImagePickerVc.selectedAssetIds indexOfObject:assetId] + 1];
_indexLabel.text = index;
_indexLabel.hidden = NO;
} else {
_indexLabel.hidden = YES;
}
_numberLabel.text = [NSString stringWithFormat:@"%zd",_tzImagePickerVc.selectedModels.count];
_numberImageView.hidden = (_tzImagePickerVc.selectedModels.count <= 0 || _isHideNaviBar || _isCropImage);
_numberLabel.hidden = (_tzImagePickerVc.selectedModels.count <= 0 || _isHideNaviBar || _isCropImage);
......@@ -508,9 +553,19 @@
}
}
- (void)refreshSelectButtonImageViewContentMode {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
if (self->_selectButton.imageView.image.size.width <= 27) {
self->_selectButton.imageView.contentMode = UIViewContentModeCenter;
} else {
self->_selectButton.imageView.contentMode = UIViewContentModeScaleAspectFit;
}
});
}
- (void)showPhotoBytes {
[[TZImageManager manager] getPhotosBytesWithArray:@[_models[_currentIndex]] completion:^(NSString *totalBytes) {
_originalPhotoLabel.text = [NSString stringWithFormat:@"(%@)",totalBytes];
self->_originalPhotoLabel.text = [NSString stringWithFormat:@"(%@)",totalBytes];
}];
}
......
......@@ -60,20 +60,20 @@
- (void)configMoviePlayer {
[[TZImageManager manager] getPhotoWithAsset:_model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
if (!isDegraded && photo) {
_cover = photo;
_doneButton.enabled = YES;
self->_cover = photo;
self->_doneButton.enabled = YES;
}
}];
[[TZImageManager manager] getVideoWithAsset:_model.asset completion:^(AVPlayerItem *playerItem, NSDictionary *info) {
dispatch_async(dispatch_get_main_queue(), ^{
_player = [AVPlayer playerWithPlayerItem:playerItem];
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
_playerLayer.frame = self.view.bounds;
[self.view.layer addSublayer:_playerLayer];
self->_player = [AVPlayer playerWithPlayerItem:playerItem];
self->_playerLayer = [AVPlayerLayer playerLayerWithPlayer:self->_player];
self->_playerLayer.frame = self.view.bounds;
[self.view.layer addSublayer:self->_playerLayer];
[self addProgressObserver];
[self configPlayButton];
[self configBottomToolBar];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pausePlayerAndShowNaviBar) name:AVPlayerItemDidPlayToEndTimeNotification object:_player.currentItem];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pausePlayerAndShowNaviBar) name:AVPlayerItemDidPlayToEndTimeNotification object:self->_player.currentItem];
});
}];
}
......@@ -121,6 +121,10 @@
[_doneButton setTitleColor:tzImagePickerVc.oKButtonTitleColorDisabled forState:UIControlStateDisabled];
[_toolBar addSubview:_doneButton];
[self.view addSubview:_toolBar];
if (tzImagePickerVc.videoPreviewPageUIConfigBlock) {
tzImagePickerVc.videoPreviewPageUIConfigBlock(_playButton, _toolBar, _doneButton);
}
}
#pragma mark - Layout
......@@ -135,6 +139,11 @@
_toolBar.frame = CGRectMake(0, self.view.tz_height - toolBarHeight, self.view.tz_width, toolBarHeight);
_doneButton.frame = CGRectMake(self.view.tz_width - 44 - 12, 0, 44, 44);
_playButton.frame = CGRectMake(0, statusBarAndNaviBarHeight, self.view.tz_width, self.view.tz_height - statusBarAndNaviBarHeight - toolBarHeight);
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (tzImagePickerVc.videoPreviewPageDidLayoutSubviewsBlock) {
tzImagePickerVc.videoPreviewPageDidLayoutSubviewsBlock(_playButton, _toolBar, _doneButton);
}
}
#pragma mark - Click Event
......@@ -155,8 +164,8 @@
}
- (void)doneButtonClick {
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
if (self.navigationController) {
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
if (imagePickerVc.autoDismiss) {
[self.navigationController dismissViewControllerAnimated:YES completion:^{
[self callDelegateMethod];
......
{
"name": "react-native-syan-image-picker",
"version": "0.1.6",
"version": "0.1.7",
"description": "React-Native 多图片选择 支持裁剪 压缩",
"main": "index.js",
"scripts": {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment