Commit 4624da7e authored by Syan's avatar Syan

add iOS 视频选择

parent ba94ebdd
......@@ -24,6 +24,7 @@ const defaultOptions = {
quality: 90, // 压缩质量
enableBase64: false, // 是否返回base64编码,默认不返回
allowPickingOriginalPhoto: false,
videoMaximumDuration: 10 * 60, // 视频最大拍摄时间,默认是10分钟,单位是秒
sortAscendingByModificationDate: true // 对照片排序,按修改时间升序,默认是YES。如果设置为NO,最新的照片会显示在最前面,内部的拍照按钮会排在第一个
};
......@@ -45,7 +46,7 @@ export default {
*
* @param {Object} options 相册参数
* @param {Function} callback 成功,或失败回调
*/
*/
showImagePicker(options, callback) {
const optionObj = {
...defaultOptions,
......@@ -79,11 +80,11 @@ export default {
* }
* @param {Object} options 相册参数
* @return {Promise} 返回一个Promise对象
*/
*/
asyncShowImagePicker(options) {
const optionObj = {
...defaultOptions,
...options,
...defaultOptions,
...options,
};
return RNSyanImagePicker.asyncShowImagePicker(optionObj);
},
......@@ -95,7 +96,7 @@ export default {
*/
openCamera(options, callback) {
const optionObj = {
...defaultOptions,
...defaultOptions,
...options
};
RNSyanImagePicker.openCamera(optionObj, callback)
......@@ -121,5 +122,19 @@ export default {
*/
removeAllPhoto() {
RNSyanImagePicker.removeAllPhoto()
},
openVideoPicker(options, callback) {
const optionObj = {
...defaultOptions,
isCamera: false,
allowPickingGif: false,
allowPickingVideo: true,
allowPickingGif: true,
allowPickingImage: false,
allowPickingMultipleVideo: true,
videoMaximumDuration: 20
};
RNSyanImagePicker.openVideoPicker(optionObj, callback)
}
};
......@@ -89,6 +89,130 @@ RCT_EXPORT_METHOD(removeAllPhoto) {
}
}
// openVideoPicker
RCT_EXPORT_METHOD(openVideoPicker:(NSDictionary *)options callback:(RCTResponseSenderBlock)callback) {
[self openTZImagePicker:options callback:callback];
}
- (void)openTZImagePicker:(NSDictionary *)options callback:(RCTResponseSenderBlock)callback {
// 照片最大可选张数
NSInteger imageCount = [options sy_integerForKey:@"imageCount"];
// 显示内部拍照按钮
BOOL isCamera = [options sy_boolForKey:@"isCamera"];
BOOL isCrop = [options sy_boolForKey:@"isCrop"];
BOOL allowPickingGif = [options sy_boolForKey:@"allowPickingGif"];
BOOL allowPickingVideo = [options sy_boolForKey:@"allowPickingVideo"];
BOOL allowPickingMultipleVideo = [options sy_boolForKey:@"allowPickingMultipleVideo"];
BOOL allowPickingImage = [options sy_boolForKey:@"allowPickingImage"];
BOOL showCropCircle = [options sy_boolForKey:@"showCropCircle"];
BOOL isRecordSelected = [options sy_boolForKey:@"isRecordSelected"];
BOOL allowPickingOriginalPhoto = [options sy_boolForKey:@"allowPickingOriginalPhoto"];
BOOL sortAscendingByModificationDate = [options sy_boolForKey:@"sortAscendingByModificationDate"];
NSInteger CropW = [options sy_integerForKey:@"CropW"];
NSInteger CropH = [options sy_integerForKey:@"CropH"];
NSInteger circleCropRadius = [options sy_integerForKey:@"circleCropRadius"];
NSInteger videoMaximumDuration = [options sy_integerForKey:@"videoMaximumDuration"];
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:imageCount delegate:nil];
imagePickerVc.maxImagesCount = imageCount;
imagePickerVc.allowPickingGif = allowPickingGif; // 允许GIF
imagePickerVc.allowTakePicture = isCamera; // 允许用户在内部拍照
imagePickerVc.allowPickingVideo = allowPickingVideo; // 不允许视频
imagePickerVc.allowPickingImage = allowPickingImage;
imagePickerVc.allowTakeVideo = NO;
imagePickerVc.videoMaximumDuration = videoMaximumDuration;
imagePickerVc.allowPickingMultipleVideo = allowPickingMultipleVideo;
imagePickerVc.allowPickingOriginalPhoto = allowPickingOriginalPhoto; // 允许原图
imagePickerVc.sortAscendingByModificationDate = sortAscendingByModificationDate;
imagePickerVc.alwaysEnableDoneBtn = YES;
imagePickerVc.allowCrop = isCrop; // 裁剪
imagePickerVc.autoDismiss = NO;
if (isRecordSelected) {
imagePickerVc.selectedAssets = self.selectedAssets; // 当前已选中的图片
}
if (imageCount == 1) {
// 单选模式
imagePickerVc.showSelectBtn = NO;
if(isCrop){
if(showCropCircle) {
imagePickerVc.needCircleCrop = showCropCircle; //圆形裁剪
imagePickerVc.circleCropRadius = circleCropRadius; //圆形半径
} else {
CGFloat x = ([[UIScreen mainScreen] bounds].size.width - CropW) / 2;
CGFloat y = ([[UIScreen mainScreen] bounds].size.height - CropH) / 2;
imagePickerVc.cropRect = CGRectMake(x,y,CropW,CropH);
}
}
}
__block TZImagePickerController *weakPicker = imagePickerVc;
[imagePickerVc setDidFinishPickingPhotosWithInfosHandle:^(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto,NSArray<NSDictionary *> *infos) {
NSMutableArray *selectArray = [NSMutableArray array];
for (NSInteger i = 0; i < assets.count; i++) {
PHAsset *asset = assets[i];
[[TZImageManager manager] getVideoOutputPathWithAsset:asset presetName:AVAssetExportPreset640x480 success:^(NSString *outputPath) {
NSMutableDictionary *video = [NSMutableDictionary dictionary];
video[@"uri"] = outputPath;
video[@"fileName"] = [asset valueForKey:@"filename"];
PHAssetResource *resource = [[PHAssetResource assetResourcesForAsset:asset] firstObject];
long long size = [[resource valueForKey:@"fileSize"] longLongValue];
video[@"size"] = @(size);
if (asset.mediaType == PHAssetMediaTypeVideo) {
video[@"type"] = @"video";
}
[selectArray addObject:video];
if(selectArray.count == assets.count) {
callback(@[[NSNull null], selectArray]);
[weakPicker dismissViewControllerAnimated:YES completion:nil];
[weakPicker hideProgressHUD];
}
} failure:^(NSString *errorMessage, NSError *error) {
NSLog(@"视频导出失败:%@,error:%@",errorMessage, error);
[weakPicker dismissViewControllerAnimated:YES completion:nil];
[weakPicker hideProgressHUD];
}];
}
}];
[imagePickerVc setDidFinishPickingVideoHandle:^(UIImage *coverImage, PHAsset *asset) {
[weakPicker showProgressHUD];
[[TZImageManager manager] getVideoOutputPathWithAsset:asset presetName:AVAssetExportPreset640x480 success:^(NSString *outputPath) {
NSLog(@"视频导出到本地完成,沙盒路径为:%@",outputPath);
NSMutableDictionary *photo = [NSMutableDictionary dictionary];
photo[@"uri"] = outputPath;
photo[@"fileName"] = [asset valueForKey:@"filename"];
PHAssetResource *resource = [[PHAssetResource assetResourcesForAsset:asset] firstObject];
long long size = [[resource valueForKey:@"fileSize"] longLongValue];
photo[@"size"] = @(size);
if (asset.mediaType == PHAssetMediaTypeVideo) {
photo[@"type"] = @"video";
}
callback(@[[NSNull null], @[photo]]);
[weakPicker dismissViewControllerAnimated:YES completion:nil];
[weakPicker hideProgressHUD];
} failure:^(NSString *errorMessage, NSError *error) {
NSLog(@"视频导出失败:%@,error:%@",errorMessage, error);
callback(@[@"视频导出失败"]);
[weakPicker dismissViewControllerAnimated:YES completion:nil];
[weakPicker hideProgressHUD];
}];
}];
__block TZImagePickerController *weakPickerVc = imagePickerVc;
[imagePickerVc setImagePickerControllerDidCancelHandle:^{
callback(@[@"取消"]);
[weakPicker dismissViewControllerAnimated:YES completion:nil];
[weakPickerVc hideProgressHUD];
}];
[[self topViewController] presentViewController:imagePickerVc animated:YES completion:nil];
}
- (void)openImagePicker {
// 照片最大可选张数
NSInteger imageCount = [self.cameraOptions sy_integerForKey:@"imageCount"];
......
......@@ -35,7 +35,6 @@ typedef enum : NSUInteger {
@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);
......
......@@ -28,33 +28,33 @@
@implementation TZAssetCell
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reload:) name:@"TZ_PHOTO_PICKER_RELOAD_NOTIFICATION" object:nil];
return self;
}
- (void)setModel:(TZAssetModel *)model {
_model = model;
self.representedAssetIdentifier = model.asset.localIdentifier;
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) {
// Set the cell's thumbnail image if it's still showing the same asset.
if ([self.representedAssetIdentifier isEqualToString:model.asset.localIdentifier]) {
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];
if (imageRequestID && self.imageRequestID && imageRequestID != self.imageRequestID) {
int32_t imageRequestID = [[TZImageManager manager] getPhotoWithAsset:model.asset photoWidth:self.tz_width completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
// Set the cell's thumbnail image if it's still showing the same asset.
if ([self.representedAssetIdentifier isEqualToString:model.asset.localIdentifier]) {
self.imageView.image = photo;
} else {
// NSLog(@"this cell is showing other asset");
[[PHImageManager defaultManager] cancelImageRequest:self.imageRequestID];
// NSLog(@"cancelImageRequest %d",self.imageRequestID);
}
self.imageRequestID = imageRequestID;
if (!isDegraded) {
[self hideProgressView];
self.imageRequestID = 0;
}
} progressHandler:nil networkAccessAllowed:NO];
if (imageRequestID && self.imageRequestID && imageRequestID != self.imageRequestID) {
[[PHImageManager defaultManager] cancelImageRequest:self.imageRequestID];
// NSLog(@"cancelImageRequest %d",self.imageRequestID);
}
self.imageRequestID = imageRequestID;
self.selectPhotoButton.selected = model.isSelected;
self.selectImageView.image = self.selectPhotoButton.isSelected ? self.photoSelImage : self.photoDefImage;
self.indexLabel.hidden = !self.selectPhotoButton.isSelected;
......@@ -73,10 +73,6 @@
} else {
[self cancelBigImageRequest];
}
if (model.needOscillatoryAnimation) {
[UIView showOscillatoryAnimationWithLayer:self.selectImageView.layer type:TZOscillatoryAnimationToBigger];
}
model.needOscillatoryAnimation = NO;
[self setNeedsLayout];
if (self.assetCellDidSetModelBlock) {
......@@ -144,9 +140,7 @@
}
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];
}
[UIView showOscillatoryAnimationWithLayer:_selectImageView.layer type:TZOscillatoryAnimationToBigger];
// 用户选中了该图片,提前获取一下大图
[self requestBigImage];
} else { // 取消选中,取消大图的获取
......@@ -185,7 +179,8 @@
[self hideProgressView];
}
} else {
*stop = YES;
// 快速连续点几次,会EXC_BAD_ACCESS...
// *stop = YES;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[self cancelBigImageRequest];
}
......@@ -199,6 +194,22 @@
[self hideProgressView];
}
#pragma mark - Notification
- (void)reload:(NSNotification *)noti {
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)noti.object;
if (self.model.isSelected && tzImagePickerVc.showSelectedIndex) {
self.index = [tzImagePickerVc.selectedAssetIds indexOfObject:self.model.asset.localIdentifier] + 1;
}
self.indexLabel.hidden = !self.selectPhotoButton.isSelected;
if (tzImagePickerVc.selectedModels.count >= tzImagePickerVc.maxImagesCount && tzImagePickerVc.showPhotoCannotSelectLayer && !self.model.isSelected) {
self.cannotSelectLayerButton.backgroundColor = tzImagePickerVc.cannotSelectLayerColor;
self.cannotSelectLayerButton.hidden = NO;
} else {
self.cannotSelectLayerButton.hidden = YES;
}
}
#pragma mark - Lazy load
- (UIButton *)selectPhotoButton {
......@@ -259,7 +270,7 @@
- (UIImageView *)videoImgView {
if (_videoImgView == nil) {
UIImageView *videoImgView = [[UIImageView alloc] init];
[videoImgView setImage:[UIImage imageNamedFromMyBundle:@"VideoSendIcon"]];
[videoImgView setImage:[UIImage tz_imageNamedFromMyBundle:@"VideoSendIcon"]];
[self.bottomView addSubview:videoImgView];
_videoImgView = videoImgView;
}
......@@ -338,6 +349,10 @@
}
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end
@interface TZAlbumCell ()
......
......@@ -23,9 +23,7 @@ typedef enum : NSUInteger {
@property (nonatomic, strong) PHAsset *asset;
@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 PHAsset
/// 用一个PHAsset实例,初始化一个照片模型
......
......@@ -58,21 +58,22 @@
- (void)getAssetFromFetchResult:(PHFetchResult *)result atIndex:(NSInteger)index allowPickingVideo:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage completion:(void (^)(TZAssetModel *model))completion;
/// Get photo 获得照片
- (void)getPostImageWithAlbumModel:(TZAlbumModel *)model completion:(void (^)(UIImage *postImage))completion;
- (PHImageRequestID)getPostImageWithAlbumModel:(TZAlbumModel *)model completion:(void (^)(UIImage *postImage))completion;
- (int32_t)getPhotoWithAsset:(PHAsset *)asset completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
- (int32_t)getPhotoWithAsset:(PHAsset *)asset photoWidth:(CGFloat)photoWidth completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
- (int32_t)getPhotoWithAsset:(PHAsset *)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:(PHAsset *)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:(PHAsset *)asset completion:(void (^)(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler;
- (PHImageRequestID)getPhotoWithAsset:(PHAsset *)asset completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
- (PHImageRequestID)getPhotoWithAsset:(PHAsset *)asset photoWidth:(CGFloat)photoWidth completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
- (PHImageRequestID)getPhotoWithAsset:(PHAsset *)asset completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed;
- (PHImageRequestID)getPhotoWithAsset:(PHAsset *)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;
- (PHImageRequestID)requestImageDataForAsset:(PHAsset *)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,则表明当前返回的是缩略图,否则是原图。
- (void)getOriginalPhotoWithAsset:(PHAsset *)asset completion:(void (^)(UIImage *photo,NSDictionary *info))completion;
- (void)getOriginalPhotoWithAsset:(PHAsset *)asset newCompletion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
- (PHImageRequestID)getOriginalPhotoWithAsset:(PHAsset *)asset completion:(void (^)(UIImage *photo,NSDictionary *info))completion;
- (PHImageRequestID)getOriginalPhotoWithAsset:(PHAsset *)asset newCompletion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
- (PHImageRequestID)getOriginalPhotoWithAsset:(PHAsset *)asset progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler newCompletion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion;
// 该方法中,completion只会走一次
- (void)getOriginalPhotoDataWithAsset:(PHAsset *)asset completion:(void (^)(NSData *data,NSDictionary *info,BOOL isDegraded))completion;
- (void)getOriginalPhotoDataWithAsset:(PHAsset *)asset progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler completion:(void (^)(NSData *data,NSDictionary *info,BOOL isDegraded))completion;
- (PHImageRequestID)getOriginalPhotoDataWithAsset:(PHAsset *)asset completion:(void (^)(NSData *data,NSDictionary *info,BOOL isDegraded))completion;
- (PHImageRequestID)getOriginalPhotoDataWithAsset:(PHAsset *)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 (^)(PHAsset *asset, NSError *error))completion;
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>StringsTable</key>
<string>Root</string>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>Title</key>
<string>Group</string>
</dict>
<dict>
<key>Type</key>
<string>PSTextFieldSpecifier</string>
<key>Title</key>
<string>Name</string>
<key>Key</key>
<string>name_preference</string>
<key>DefaultValue</key>
<string></string>
<key>IsSecure</key>
<false/>
<key>KeyboardType</key>
<string>Alphabet</string>
<key>AutocapitalizationType</key>
<string>None</string>
<key>AutocorrectionType</key>
<string>No</string>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Enabled</string>
<key>Key</key>
<string>enabled_preference</string>
<key>DefaultValue</key>
<true/>
</dict>
<dict>
<key>Type</key>
<string>PSSliderSpecifier</string>
<key>Key</key>
<string>slider_preference</string>
<key>DefaultValue</key>
<real>0.5</real>
<key>MinimumValue</key>
<integer>0</integer>
<key>MaximumValue</key>
<integer>1</integer>
<key>MinimumValueImage</key>
<string></string>
<key>MaximumValueImage</key>
<string></string>
</dict>
</array>
</dict>
</plist>
......@@ -9,6 +9,7 @@
"Preview" = "Xem trước";
"Full image" = "Hình gốc";
"Processing..." = "Đang xử lý...";
"No Photos or Videos" = "Không có ảnh hoặc video";
"Can not use camera" = "Máy chụp hình không khả dụng";
"Synchronizing photos from iCloud" = "Đang đồng bộ hình ảnh từ ICloud";
"Can not choose both video and photo" = "Trong lúc chọn hình ảnh không cùng lúc chọn video";
......
......@@ -4,7 +4,7 @@
//
// Created by 谭真 on 15/12/24.
// Copyright © 2015年 谭真. All rights reserved.
// version 3.0.9 - 2018.10.09
// version 3.1.9 - 2019.01.14
// 更多信息,请前往项目的github地址:https://github.com/banchichen/TZImagePickerController
/*
......@@ -127,8 +127,8 @@
/// 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像素宽
/// Default is YES, if set NO, the result photo will be scaled to photoWidth pixel width. The photoWidth default is 828px
/// 默认是YES,如果设置为NO,内部会缩放图片到photoWidth像素宽
@property (assign, nonatomic) BOOL notScaleImage;
/// 默认是NO,如果设置为YES,导出视频时会修正转向(慎重设为YES,可能导致部分安卓下拍的视频导出失败)
......@@ -230,26 +230,11 @@
#pragma mark -
- (void)cancelButtonClick;
// The picker should dismiss itself; when it dismissed these handle will be called.
// You can also set autoDismiss to NO, then the picker don't dismiss itself.
// If isOriginalPhoto is YES, user picked the original photo.
// You can get original photo with asset, by the method [[TZImageManager manager] getOriginalPhotoWithAsset:completion:].
// The UIImage Object in photos default width is 828px, you can set it by photoWidth property.
// 这个照片选择器会自己dismiss,当选择器dismiss的时候,会执行下面的handle
// 你也可以设置autoDismiss属性为NO,选择器就不会自己dismis了
// 如果isSelectOriginalPhoto为YES,表明用户选择了原图
// 你可以通过一个asset获得原图,通过这个方法:[[TZImageManager manager] getOriginalPhotoWithAsset:completion:]
// photos数组里的UIImage对象,默认是828像素宽,你可以通过设置photoWidth属性的值来改变它
// For method annotations, see the corresponding method in TZImagePickerControllerDelegate / 方法注释见TZImagePickerControllerDelegate中对应方法
@property (nonatomic, copy) void (^didFinishPickingPhotosHandle)(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto);
@property (nonatomic, copy) void (^didFinishPickingPhotosWithInfosHandle)(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto,NSArray<NSDictionary *> *infos);
@property (nonatomic, copy) void (^imagePickerControllerDidCancelHandle)(void);
// If user picking a video, this handle will be called.
// 如果用户选择了一个视频,下面的handle会被执行
@property (nonatomic, copy) void (^didFinishPickingVideoHandle)(UIImage *coverImage,PHAsset *asset);
// If user picking a gif image, this callback will be called.
// 如果用户选择了一个gif图片,下面的handle会被执行
@property (nonatomic, copy) void (^didFinishPickingGifImageHandle)(UIImage *animatedImage,id sourceAssets);
@property (nonatomic, weak) id<TZImagePickerControllerDelegate> pickerDelegate;
......@@ -259,27 +244,30 @@
@protocol TZImagePickerControllerDelegate <NSObject>
@optional
// The picker should dismiss itself; when it dismissed these handle will be called.
// The picker should dismiss itself; when it dismissed these callback will be called.
// You can also set autoDismiss to NO, then the picker don't dismiss itself.
// If isOriginalPhoto is YES, user picked the original photo.
// You can get original photo with asset, by the method [[TZImageManager manager] getOriginalPhotoWithAsset:completion:].
// The UIImage Object in photos default width is 828px, you can set it by photoWidth property.
// 这个照片选择器会自己dismiss,当选择器dismiss的时候,会执行下面的handle
// 这个照片选择器会自己dismiss,当选择器dismiss的时候,会执行下面的代理方法
// 你也可以设置autoDismiss属性为NO,选择器就不会自己dismis了
// 如果isSelectOriginalPhoto为YES,表明用户选择了原图
// 你可以通过一个asset获得原图,通过这个方法:[[TZImageManager manager] getOriginalPhotoWithAsset:completion:]
// photos数组里的UIImage对象,默认是828像素宽,你可以通过设置photoWidth属性的值来改变它
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto;
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto infos:(NSArray<NSDictionary *> *)infos;
//- (void)imagePickerControllerDidCancel:(TZImagePickerController *)picker __attribute__((deprecated("Use -tz_imagePickerControllerDidCancel:.")));
- (void)tz_imagePickerControllerDidCancel:(TZImagePickerController *)picker;
// If user picking a video, this callback will be called.
// 如果用户选择了一个视频,下面的handle会被执行
// If user picking a video and allowPickingMultipleVideo is NO, this callback will be called.
// If allowPickingMultipleVideo is YES, will call imagePickerController:didFinishPickingPhotos:sourceAssets:isSelectOriginalPhoto:
// 如果用户选择了一个视频且allowPickingMultipleVideo是NO,下面的代理方法会被执行
// 如果allowPickingMultipleVideo是YES,将会调用imagePickerController:didFinishPickingPhotos:sourceAssets:isSelectOriginalPhoto:
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingVideo:(UIImage *)coverImage sourceAssets:(PHAsset *)asset;
// If user picking a gif image, this callback will be called.
// 如果用户选择了一个gif图片,下面的handle会被执行
// If user picking a gif image and allowPickingMultipleVideo is NO, this callback will be called.
// If allowPickingMultipleVideo is YES, will call imagePickerController:didFinishPickingPhotos:sourceAssets:isSelectOriginalPhoto:
// 如果用户选择了一个gif图片且allowPickingMultipleVideo是NO,下面的代理方法会被执行
// 如果allowPickingMultipleVideo是YES,将会调用imagePickerController:didFinishPickingPhotos:sourceAssets:isSelectOriginalPhoto:
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingGifImage:(UIImage *)animatedImage sourceAssets:(PHAsset *)asset;
// Decide album show or not't
......@@ -300,7 +288,7 @@
@interface UIImage (MyBundle)
+ (UIImage *)imageNamedFromMyBundle:(NSString *)name;
+ (UIImage *)tz_imageNamedFromMyBundle:(NSString *)name;
@end
......@@ -309,7 +297,7 @@
+ (CGFloat)tz_statusBarHeight;
// 获得Info.plist数据字典
+ (NSDictionary *)tz_getInfoDictionary;
+ (BOOL)isRightToLeftLayout;
+ (BOOL)tz_isRightToLeftLayout;
@end
......
......@@ -4,7 +4,7 @@
//
// Created by 谭真 on 15/12/24.
// Copyright © 2015年 谭真. All rights reserved.
// version 3.0.9 - 2018.10.09
// version 3.1.9 - 2019.01.14
// 更多信息,请前往项目的github地址:https://github.com/banchichen/TZImagePickerController
#import "TZImagePickerController.h"
......@@ -235,6 +235,7 @@
self = [super initWithRootViewController:previewVc];
if (self) {
self.maxImagesCount = 1;
self.allowPickingImage = YES;
self.allowCrop = YES;
self.selectedAssets = [NSMutableArray arrayWithArray:@[asset]];
[self configDefaultSetting];
......@@ -290,37 +291,37 @@
- (void)setTakePictureImageName:(NSString *)takePictureImageName {
_takePictureImageName = takePictureImageName;
_takePictureImage = [UIImage imageNamedFromMyBundle:takePictureImageName];
_takePictureImage = [UIImage tz_imageNamedFromMyBundle:takePictureImageName];
}
- (void)setPhotoSelImageName:(NSString *)photoSelImageName {
_photoSelImageName = photoSelImageName;
_photoSelImage = [UIImage imageNamedFromMyBundle:photoSelImageName];
_photoSelImage = [UIImage tz_imageNamedFromMyBundle:photoSelImageName];
}
- (void)setPhotoDefImageName:(NSString *)photoDefImageName {
_photoDefImageName = photoDefImageName;
_photoDefImage = [UIImage imageNamedFromMyBundle:photoDefImageName];
_photoDefImage = [UIImage tz_imageNamedFromMyBundle:photoDefImageName];
}
- (void)setPhotoNumberIconImageName:(NSString *)photoNumberIconImageName {
_photoNumberIconImageName = photoNumberIconImageName;
_photoNumberIconImage = [UIImage imageNamedFromMyBundle:photoNumberIconImageName];
_photoNumberIconImage = [UIImage tz_imageNamedFromMyBundle:photoNumberIconImageName];
}
- (void)setPhotoPreviewOriginDefImageName:(NSString *)photoPreviewOriginDefImageName {
_photoPreviewOriginDefImageName = photoPreviewOriginDefImageName;
_photoPreviewOriginDefImage = [UIImage imageNamedFromMyBundle:photoPreviewOriginDefImageName];
_photoPreviewOriginDefImage = [UIImage tz_imageNamedFromMyBundle:photoPreviewOriginDefImageName];
}
- (void)setPhotoOriginDefImageName:(NSString *)photoOriginDefImageName {
_photoOriginDefImageName = photoOriginDefImageName;
_photoOriginDefImage = [UIImage imageNamedFromMyBundle:photoOriginDefImageName];
_photoOriginDefImage = [UIImage tz_imageNamedFromMyBundle:photoOriginDefImageName];
}
- (void)setPhotoOriginSelImageName:(NSString *)photoOriginSelImageName {
_photoOriginSelImageName = photoOriginSelImageName;
_photoOriginSelImage = [UIImage imageNamedFromMyBundle:photoOriginSelImageName];
_photoOriginSelImage = [UIImage tz_imageNamedFromMyBundle:photoOriginSelImageName];
}
- (void)setIconThemeColor:(UIColor *)iconThemeColor {
......@@ -821,7 +822,7 @@
@implementation UIImage (MyBundle)
+ (UIImage *)imageNamedFromMyBundle:(NSString *)name {
+ (UIImage *)tz_imageNamedFromMyBundle:(NSString *)name {
NSBundle *imageBundle = [NSBundle tz_imagePickerBundle];
name = [name stringByAppendingString:@"@2x"];
NSString *imagePath = [imageBundle pathForResource:name ofType:@"png"];
......@@ -863,7 +864,7 @@
return infoDict ? infoDict : @{};
}
+ (BOOL)isRightToLeftLayout {
+ (BOOL)tz_isRightToLeftLayout {
if (@available(iOS 9.0, *)) {
if ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:UISemanticContentAttributeUnspecified] == UIUserInterfaceLayoutDirectionRightToLeft) {
return YES;
......
//
// TZImageRequestOperation.h
// TZImagePickerControllerFramework
//
// Created by 谭真 on 2018/12/20.
// Copyright © 2018 谭真. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Photos/Photos.h>
NS_ASSUME_NONNULL_BEGIN
@interface TZImageRequestOperation : NSOperation
typedef void(^TZImageRequestCompletedBlock)(UIImage *photo, NSDictionary *info, BOOL isDegraded);
typedef void(^TZImageRequestProgressBlock)(double progress, NSError *error, BOOL *stop, NSDictionary *info);
@property (nonatomic, copy, nullable) TZImageRequestCompletedBlock completedBlock;
@property (nonatomic, copy, nullable) TZImageRequestProgressBlock progressBlock;
@property (nonatomic, strong, nullable) PHAsset *asset;
@property (assign, nonatomic, getter = isExecuting) BOOL executing;
@property (assign, nonatomic, getter = isFinished) BOOL finished;
- (instancetype)initWithAsset:(PHAsset *)asset completion:(TZImageRequestCompletedBlock)completionBlock progressHandler:(TZImageRequestProgressBlock)progressHandler;
- (void)done;
@end
NS_ASSUME_NONNULL_END
//
// TZImageRequestOperation.m
// TZImagePickerControllerFramework
//
// Created by 谭真 on 2018/12/20.
// Copyright © 2018 谭真. All rights reserved.
//
#import "TZImageRequestOperation.h"
#import "TZImageManager.h"
@implementation TZImageRequestOperation
@synthesize executing = _executing;
@synthesize finished = _finished;
- (instancetype)initWithAsset:(PHAsset *)asset completion:(TZImageRequestCompletedBlock)completionBlock progressHandler:(TZImageRequestProgressBlock)progressHandler {
self = [super init];
self.asset = asset;
self.completedBlock = completionBlock;
self.progressBlock = progressHandler;
_executing = NO;
_finished = NO;
return self;
}
- (void)start {
self.executing = YES;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[[TZImageManager manager] getPhotoWithAsset:self.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
dispatch_async(dispatch_get_main_queue(), ^{
if (!isDegraded) {
if (self.completedBlock) {
self.completedBlock(photo, info, isDegraded);
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self done];
});
}
});
} progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
dispatch_async(dispatch_get_main_queue(), ^{
if (self.progressBlock) {
self.progressBlock(progress, error, stop, info);
}
});
} networkAccessAllowed:YES];
});
}
- (void)done {
self.finished = YES;
self.executing = NO;
[self reset];
}
- (void)reset {
self.asset = nil;
self.completedBlock = nil;
self.progressBlock = nil;
}
- (void)setFinished:(BOOL)finished {
[self willChangeValueForKey:@"isFinished"];
_finished = finished;
[self didChangeValueForKey:@"isFinished"];
}
- (void)setExecuting:(BOOL)executing {
[self willChangeValueForKey:@"isExecuting"];
_executing = executing;
[self didChangeValueForKey:@"isExecuting"];
}
- (BOOL)isAsynchronous {
return YES;
}
@end
......@@ -12,7 +12,7 @@
@interface TZLocationManager : NSObject
+ (instancetype)manager;
+ (instancetype)manager NS_SWIFT_NAME(default());
/// 开始定位
- (void)startLocation;
......
......@@ -17,6 +17,7 @@
#import "TZGifPhotoPreviewController.h"
#import "TZLocationManager.h"
#import <MobileCoreServices/MobileCoreServices.h>
#import "TZImageRequestOperation.h"
@interface TZPhotoPickerController ()<UICollectionViewDataSource,UICollectionViewDelegate,UIImagePickerControllerDelegate,UINavigationControllerDelegate,UIAlertViewDelegate> {
NSMutableArray *_models;
......@@ -38,10 +39,11 @@
@property CGRect previousPreheatRect;
@property (nonatomic, assign) BOOL isSelectOriginalPhoto;
@property (nonatomic, strong) TZCollectionView *collectionView;
@property (nonatomic, strong) UILabel *noDataLabel;
@property (strong, nonatomic) UICollectionViewFlowLayout *layout;
@property (nonatomic, strong) UIImagePickerController *imagePickerVc;
@property (strong, nonatomic) CLLocation *location;
@property (assign, nonatomic) BOOL useCachedImage;
@property (nonatomic, strong) NSOperationQueue *operationQueue;
@end
static CGSize AssetGridThumbnailSize;
......@@ -93,6 +95,9 @@ static CGFloat itemMargin = 5;
_showTakePhotoBtn = _model.isCameraRoll && ((tzImagePickerVc.allowTakePicture && tzImagePickerVc.allowPickingImage) || (tzImagePickerVc.allowTakeVideo && tzImagePickerVc.allowPickingVideo));
// [self resetCachedAssets];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeStatusBarOrientationNotification:) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
self.operationQueue = [[NSOperationQueue alloc] init];
self.operationQueue.maxConcurrentOperationCount = 3;
}
- (void)fetchAssetModels {
......@@ -166,6 +171,15 @@ static CGFloat itemMargin = 5;
_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);
if (_models.count == 0) {
_noDataLabel = [UILabel new];
_noDataLabel.textAlignment = NSTextAlignmentCenter;
_noDataLabel.text = [NSBundle tz_localizedStringForKey:@"No Photos or Videos"];
CGFloat rgb = 153 / 256.0;
_noDataLabel.textColor = [UIColor colorWithRed:rgb green:rgb blue:rgb alpha:1.0];
_noDataLabel.font = [UIFont boldSystemFontOfSize:20];
[_collectionView addSubview:_noDataLabel];
}
}
[self.view addSubview:_collectionView];
[_collectionView registerClass:[TZAssetCell class] forCellWithReuseIdentifier:@"TZAssetCell"];
......@@ -211,7 +225,7 @@ static CGFloat itemMargin = 5;
if (tzImagePickerVc.allowPickingOriginalPhoto) {
_originalPhotoButton = [UIButton buttonWithType:UIButtonTypeCustom];
_originalPhotoButton.imageEdgeInsets = UIEdgeInsetsMake(0, [TZCommonTools isRightToLeftLayout] ? 10 : -10, 0, 0);
_originalPhotoButton.imageEdgeInsets = UIEdgeInsetsMake(0, [TZCommonTools tz_isRightToLeftLayout] ? 10 : -10, 0, 0);
[_originalPhotoButton addTarget:self action:@selector(originalPhotoButtonClick) forControlEvents:UIControlEventTouchUpInside];
_originalPhotoButton.titleLabel.font = [UIFont systemFontOfSize:16];
[_originalPhotoButton setTitle:tzImagePickerVc.fullImageBtnTitleStr forState:UIControlStateNormal];
......@@ -293,6 +307,7 @@ static CGFloat itemMargin = 5;
collectionViewHeight = tzImagePickerVc.showSelectBtn ? self.view.tz_height - toolBarHeight : self.view.tz_height;
}
_collectionView.frame = CGRectMake(0, top, self.view.tz_width, collectionViewHeight);
_noDataLabel.frame = _collectionView.bounds;
CGFloat itemWH = (self.view.tz_width - (self.columnNumber + 1) * itemMargin) / self.columnNumber;
_layout.itemSize = CGSizeMake(itemWH, itemWH);
_layout.minimumInteritemSpacing = itemMargin;
......@@ -330,6 +345,7 @@ static CGFloat itemMargin = 5;
_divideLine.frame = CGRectMake(0, 0, self.view.tz_width, 1);
[TZImageManager manager].columnNumber = [TZImageManager manager].columnNumber;
[TZImageManager manager].photoWidth = tzImagePickerVc.photoWidth;
[self.collectionView reloadData];
if (tzImagePickerVc.photoPickerPageDidLayoutSubviewsBlock) {
......@@ -389,7 +405,7 @@ static CGFloat itemMargin = 5;
__block UIAlertController *alertView;
for (NSInteger i = 0; i < tzImagePickerVc.selectedModels.count; i++) {
TZAssetModel *model = tzImagePickerVc.selectedModels[i];
[[TZImageManager manager] getPhotoWithAsset:model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
TZImageRequestOperation *operation = [[TZImageRequestOperation alloc] initWithAsset:model.asset completion:^(UIImage * _Nonnull photo, NSDictionary * _Nonnull info, BOOL isDegraded) {
if (isDegraded) return;
if (photo) {
if (![TZImagePickerConfig sharedInstance].notScaleImage) {
......@@ -406,7 +422,7 @@ static CGFloat itemMargin = 5;
[tzImagePickerVc hideAlertView:alertView];
[self didGetAllPhotos:photos assets:assets infoArr:infoArr];
}
} progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
} progressHandler:^(double progress, NSError * _Nonnull error, BOOL * _Nonnull stop, NSDictionary * _Nonnull info) {
// 如果图片正在从iCloud同步中,提醒用户
if (progress < 1 && havenotShowAlert && !alertView) {
[tzImagePickerVc hideProgressHUD];
......@@ -417,7 +433,8 @@ static CGFloat itemMargin = 5;
if (progress >= 1) {
havenotShowAlert = YES;
}
} networkAccessAllowed:YES];
}];
[self.operationQueue addOperation:operation];
}
}
if (tzImagePickerVc.selectedModels.count <= 0 || tzImagePickerVc.onlyReturnAsset) {
......@@ -495,7 +512,6 @@ static CGFloat itemMargin = 5;
cell.allowPickingMultipleVideo = tzImagePickerVc.allowPickingMultipleVideo;
cell.photoDefImage = tzImagePickerVc.photoDefImage;
cell.photoSelImage = tzImagePickerVc.photoSelImage;
cell.useCachedImage = self.useCachedImage;
cell.assetCellDidSetModelBlock = tzImagePickerVc.assetCellDidSetModelBlock;
cell.assetCellDidLayoutSubviewsBlock = tzImagePickerVc.assetCellDidLayoutSubviewsBlock;
TZAssetModel *model;
......@@ -540,7 +556,7 @@ static CGFloat itemMargin = 5;
}
[strongSelf refreshBottomToolBarStatus];
if (tzImagePickerVc.showSelectedIndex || tzImagePickerVc.showPhotoCannotSelectLayer) {
[strongSelf setUseCachedImageAndReloadData];
[[NSNotificationCenter defaultCenter] postNotificationName:@"TZ_PHOTO_PICKER_RELOAD_NOTIFICATION" object:strongSelf.navigationController];
}
[UIView showOscillatoryAnimationWithLayer:strongLayer type:TZOscillatoryAnimationToSmaller];
} else {
......@@ -554,11 +570,10 @@ static CGFloat itemMargin = 5;
}
strongCell.selectPhotoButton.selected = YES;
model.isSelected = YES;
[tzImagePickerVc addSelectedModel:model];
if (tzImagePickerVc.showSelectedIndex || tzImagePickerVc.showPhotoCannotSelectLayer) {
model.needOscillatoryAnimation = YES;
[strongSelf setUseCachedImageAndReloadData];
[[NSNotificationCenter defaultCenter] postNotificationName:@"TZ_PHOTO_PICKER_RELOAD_NOTIFICATION" object:strongSelf.navigationController];
}
[tzImagePickerVc addSelectedModel:model];
[strongSelf refreshBottomToolBarStatus];
[UIView showOscillatoryAnimationWithLayer:strongLayer type:TZOscillatoryAnimationToSmaller];
} else {
......@@ -616,14 +631,6 @@ 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];
......
......@@ -58,6 +58,7 @@
@property (strong, nonatomic) AVPlayerLayer *playerLayer;
@property (strong, nonatomic) UIButton *playButton;
@property (strong, nonatomic) UIImage *cover;
@property (nonatomic, strong) NSURL *videoURL;
- (void)pausePlayerAndShowNaviBar;
@end
......
......@@ -224,6 +224,8 @@
self.imageRequestID = 0;
}
} networkAccessAllowed:YES];
[self configMaximumZoomScale];
}
- (void)recoverSubviews {
......@@ -257,9 +259,8 @@
[self refreshScrollViewContentSize];
}
- (void)setAllowCrop:(BOOL)allowCrop {
_allowCrop = allowCrop;
_scrollView.maximumZoomScale = allowCrop ? 4.0 : 2.5;
- (void)configMaximumZoomScale {
_scrollView.maximumZoomScale = _allowCrop ? 4.0 : 2.5;
if ([self.asset isKindOfClass:[PHAsset class]]) {
PHAsset *phAsset = (PHAsset *)self.asset;
......@@ -354,7 +355,7 @@
@implementation TZVideoPreviewCell
- (void)configSubviews {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pausePlayerAndShowNaviBar) name:UIApplicationWillResignActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActiveNotification) name:UIApplicationWillResignActiveNotification object:nil];
}
- (void)configPlayButton {
......@@ -362,8 +363,8 @@
[_playButton removeFromSuperview];
}
_playButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
[_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlayHL"] forState:UIControlStateHighlighted];
[_playButton setImage:[UIImage tz_imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
[_playButton setImage:[UIImage tz_imageNamedFromMyBundle:@"MMVideoPreviewPlayHL"] forState:UIControlStateHighlighted];
[_playButton addTarget:self action:@selector(playButtonClick) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_playButton];
}
......@@ -373,6 +374,11 @@
[self configMoviePlayer];
}
- (void)setVideoURL:(NSURL *)videoURL {
_videoURL = videoURL;
[self configMoviePlayer];
}
- (void)configMoviePlayer {
if (_player) {
[_playerLayer removeFromSuperlayer];
......@@ -381,20 +387,29 @@
_player = nil;
}
[[TZImageManager manager] getPhotoWithAsset:self.model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
self->_cover = photo;
}];
[[TZImageManager manager] getVideoWithAsset:self.model.asset completion:^(AVPlayerItem *playerItem, NSDictionary *info) {
dispatch_async(dispatch_get_main_queue(), ^{
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:self->_player.currentItem];
});
}];
if (self.model && self.model.asset) {
[[TZImageManager manager] getPhotoWithAsset:self.model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
self.cover = photo;
}];
[[TZImageManager manager] getVideoWithAsset:self.model.asset completion:^(AVPlayerItem *playerItem, NSDictionary *info) {
dispatch_async(dispatch_get_main_queue(), ^{
[self configPlayerWithItem:playerItem];
});
}];
} else {
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:self.videoURL];
[self configPlayerWithItem:playerItem];
}
}
- (void)configPlayerWithItem:(AVPlayerItem *)playerItem {
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:self.player.currentItem];
}
- (void)layoutSubviews {
......@@ -404,7 +419,17 @@
}
- (void)photoPreviewCollectionViewDidScroll {
[self pausePlayerAndShowNaviBar];
if (_player && _player.rate != 0.0) {
[self pausePlayerAndShowNaviBar];
}
}
#pragma mark - Notification
- (void)appWillResignActiveNotification {
if (_player && _player.rate != 0.0) {
[self pausePlayerAndShowNaviBar];
}
}
#pragma mark - Click Event
......@@ -426,12 +451,10 @@
}
- (void)pausePlayerAndShowNaviBar {
if (_player.rate != 0.0) {
[_player pause];
[_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
if (self.singleTapGestureBlock) {
self.singleTapGestureBlock();
}
[_player pause];
[_playButton setImage:[UIImage tz_imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
if (self.singleTapGestureBlock) {
self.singleTapGestureBlock();
}
}
......
......@@ -105,7 +105,7 @@
_naviBar.backgroundColor = [UIColor colorWithRed:(34/255.0) green:(34/255.0) blue:(34/255.0) alpha:0.7];
_backButton = [[UIButton alloc] initWithFrame:CGRectZero];
[_backButton setImage:[UIImage imageNamedFromMyBundle:@"navi_back"] forState:UIControlStateNormal];
[_backButton setImage:[UIImage tz_imageNamedFromMyBundle:@"navi_back"] forState:UIControlStateNormal];
[_backButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_backButton addTarget:self action:@selector(backButtonClick) forControlEvents:UIControlEventTouchUpInside];
......@@ -137,7 +137,7 @@
TZImagePickerController *_tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (_tzImagePickerVc.allowPickingOriginalPhoto) {
_originalPhotoButton = [UIButton buttonWithType:UIButtonTypeCustom];
_originalPhotoButton.imageEdgeInsets = UIEdgeInsetsMake(0, [TZCommonTools isRightToLeftLayout] ? 10 : -10, 0, 0);
_originalPhotoButton.imageEdgeInsets = UIEdgeInsetsMake(0, [TZCommonTools tz_isRightToLeftLayout] ? 10 : -10, 0, 0);
_originalPhotoButton.backgroundColor = [UIColor clearColor];
[_originalPhotoButton addTarget:self action:@selector(originalPhotoButtonClick) forControlEvents:UIControlEventTouchUpInside];
_originalPhotoButton.titleLabel.font = [UIFont systemFontOfSize:13];
......@@ -502,7 +502,10 @@
if ([cell isKindOfClass:[TZPhotoPreviewCell class]]) {
[(TZPhotoPreviewCell *)cell recoverSubviews];
} else if ([cell isKindOfClass:[TZVideoPreviewCell class]]) {
[(TZVideoPreviewCell *)cell pausePlayerAndShowNaviBar];
TZVideoPreviewCell *videoCell = (TZVideoPreviewCell *)cell;
if (videoCell.player && videoCell.player.rate != 0.0) {
[videoCell pausePlayerAndShowNaviBar];
}
}
}
......@@ -574,7 +577,7 @@
}
- (NSInteger)currentIndex {
return [TZCommonTools isRightToLeftLayout] ? self.models.count - _currentIndex - 1 : _currentIndex;
return [TZCommonTools tz_isRightToLeftLayout] ? self.models.count - _currentIndex - 1 : _currentIndex;
}
@end
......@@ -93,8 +93,8 @@
- (void)configPlayButton {
_playButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
[_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlayHL"] forState:UIControlStateHighlighted];
[_playButton setImage:[UIImage tz_imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
[_playButton setImage:[UIImage tz_imageNamedFromMyBundle:@"MMVideoPreviewPlayHL"] forState:UIControlStateHighlighted];
[_playButton addTarget:self action:@selector(playButtonClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_playButton];
}
......@@ -204,7 +204,7 @@
[_player pause];
_toolBar.hidden = NO;
[self.navigationController setNavigationBarHidden:NO];
[_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
[_playButton setImage:[UIImage tz_imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
if (self.needShowStatusBar) {
[UIApplication sharedApplication].statusBarHidden = NO;
......
{
"name": "react-native-syan-image-picker",
"version": "0.3.0",
"version": "0.3.1",
"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