Commit 69ea2ec4 authored by 少言's avatar 少言

0.1.1-新增base64-新增删除缓存方法

parent 1ef430dc
......@@ -3,7 +3,9 @@ package com.reactlibrary;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.BaseActivityEventListener;
......@@ -18,11 +20,12 @@ import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.bridge.WritableNativeMap;
import com.luck.picture.lib.PictureSelector;
import com.luck.picture.lib.compress.Luban;
import com.luck.picture.lib.config.PictureConfig;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.tools.PictureFileUtils;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
......@@ -70,10 +73,18 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
this.openCamera(options);
}
/**
* 缓存清除
* 包括裁剪和压缩后的缓存,要在上传成功后调用,注意:需要系统sd卡权限
*/
@ReactMethod
public void deleteCache() {
Activity currentActivity = getCurrentActivity();
PictureFileUtils.deleteCacheDirFile(currentActivity);
}
/**
* 打开相册选择
*
* @param options 相册参数
*/
private void openImagePicker(ReadableMap options) {
......@@ -132,9 +143,8 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
}
/**
* 打开相册选择
*
* @param options 相册参数
* 打开相机
* @param options
*/
private void openCamera(ReadableMap options) {
boolean isCrop = options.getBoolean("isCrop");
......@@ -179,6 +189,7 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
WritableMap aImage = new WritableNativeMap();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
if (!media.isCompressed()) {
BitmapFactory.decodeFile(media.getPath(), options);
......@@ -186,6 +197,18 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
aImage.putDouble("height", options.outHeight);
aImage.putString("type", "image");
aImage.putString("uri", "file://" + media.getPath());
//decode to bitmap
Bitmap bitmap = BitmapFactory.decodeFile(media.getPath());
//convert to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] bytes = baos.toByteArray();
//base64 encode
byte[] encode = Base64.encode(bytes,Base64.DEFAULT);
String encodeString = new String(encode);
aImage.putString("base64", encodeString);
} else {
// 压缩过,取 media.getCompressPath();
BitmapFactory.decodeFile(media.getCompressPath(), options);
......@@ -193,6 +216,17 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
aImage.putDouble("height", options.outHeight);
aImage.putString("type", "image");
aImage.putString("uri", "file://" + media.getCompressPath());
//decode to bitmap
Bitmap bitmap = BitmapFactory.decodeFile(media.getCompressPath());
//convert to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] bytes = baos.toByteArray();
//base64 encode
byte[] encode = Base64.encode(bytes,Base64.DEFAULT);
String encodeString = new String(encode);
aImage.putString("base64", encodeString);
}
if (media.isCut()) {
......@@ -214,7 +248,6 @@ public class RNSyanImagePickerModule extends ReactContextBaseJavaModule {
/**
* 选择照片成功时触发
*
* @param imageList 图片数组
*/
private void invokeSuccessWithResult(WritableArray imageList) {
......
......@@ -95,5 +95,12 @@ export default {
...options
};
RNSyanImagePicker.openCamera(optionObj, callback)
},
/**
* 清除缓存
*/
deleteCache() {
RNSyanImagePicker.deleteCache()
}
};
......@@ -9,9 +9,7 @@
@interface RNSyanImagePicker ()
@property (nonatomic, strong) UIImagePickerController *imagePickerVc;
@property (nonatomic, strong) NSDictionary *cameraOptions;
/**
保存Promise的resolve block
*/
......@@ -30,14 +28,6 @@
RCT_EXPORT_MODULE()
- (UIImagePickerController *)imagePickerVc {
if (_imagePickerVc == nil) {
_imagePickerVc = [[UIImagePickerController alloc] init];
_imagePickerVc.delegate = self;
}
return _imagePickerVc;
}
RCT_EXPORT_METHOD(showImagePicker:(NSDictionary *)options
callback:(RCTResponseSenderBlock)callback) {
self.callback = callback;
......@@ -56,6 +46,20 @@ RCT_REMAP_METHOD(asyncShowImagePicker,
[self openImagePickerWithOptions:options];
}
RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options callback:(RCTResponseSenderBlock)callback) {
self.cameraOptions = options;
self.callback = callback;
self.resolveBlock = nil;
self.rejectBlock = nil;
[self takePhoto];
}
RCT_EXPORT_METHOD(deleteCache) {
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath: [NSString stringWithFormat:@"%@ImageCaches", NSTemporaryDirectory()] error:nil];
}
- (void)openImagePickerWithOptions:(NSDictionary *)options {
// 照片最大可选张数
NSInteger imageCount = [options sy_integerForKey:@"imageCount"];
......@@ -67,7 +71,7 @@ RCT_REMAP_METHOD(asyncShowImagePicker,
NSInteger CropW = [options sy_integerForKey:@"CropW"];
NSInteger CropH = [options sy_integerForKey:@"CropH"];
NSInteger circleCropRadius = [options sy_integerForKey:@"circleCropRadius"];
NSInteger quality = [options sy_integerForKey:@"quality"];
NSInteger quality = [self.cameraOptions sy_integerForKey:@"quality"];
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:imageCount delegate:nil];
......@@ -94,26 +98,19 @@ RCT_REMAP_METHOD(asyncShowImagePicker,
}
}
}
__block TZImagePickerController *weakPicker = imagePickerVc;
[imagePickerVc setDidFinishPickingPhotosWithInfosHandle:^(NSArray<UIImage *> *photos,NSArray *assets,BOOL isSelectOriginalPhoto,NSArray<NSDictionary *> *infos) {
NSMutableArray *selectedPhotos = [NSMutableArray array];
[weakPicker showProgressHUD];
if (imageCount == 1 && isCrop) {
[selectedPhotos addObject:[self handleImageData:photos[0] quality:quality]];
} else {
[infos enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[selectedPhotos addObject:[self handleImageData:photos[idx] quality:quality]];
}];
}
[self invokeSuccessWithResult:selectedPhotos];
[weakPicker hideProgressHUD];
}];
......@@ -124,17 +121,15 @@ RCT_REMAP_METHOD(asyncShowImagePicker,
[[self topViewController] presentViewController:imagePickerVc animated:YES completion:nil];
}
RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options callback:(RCTResponseSenderBlock)callback) {
self.cameraOptions = options;
self.callback = callback;
self.resolveBlock = nil;
self.rejectBlock = nil;
[self takePhoto];
- (UIImagePickerController *)imagePickerVc {
if (_imagePickerVc == nil) {
_imagePickerVc = [[UIImagePickerController alloc] init];
_imagePickerVc.delegate = self;
}
return _imagePickerVc;
}
#pragma mark - UIImagePickerController
- (void)takePhoto {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if ((authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied) && iOS7Later) {
......@@ -179,7 +174,6 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options callback:(RCTResponseSender
// 调用相机
- (void)pushImagePickerController {
UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) {
self.imagePickerVc.sourceType = sourceType;
......@@ -187,7 +181,6 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options callback:(RCTResponseSender
self.imagePickerVc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
}
[[self topViewController] presentViewController:self.imagePickerVc animated:YES completion:nil];
} else {
NSLog(@"模拟器中无法打开照相机,请在真机中使用");
}
......@@ -209,12 +202,11 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options callback:(RCTResponseSender
[tzImagePickerVc hideProgressHUD];
NSLog(@"图片保存失败 %@",error);
} else {
[[TZImageManager manager] getCameraRollAlbum:NO allowPickingImage:YES completion:^(TZAlbumModel *model) {
[[TZImageManager manager] getCameraRollAlbum:NO allowPickingImage:YES needFetchAssets:YES completion:^(TZAlbumModel *model) {
[[TZImageManager manager] getAssetsFromFetchResult:model.result allowPickingVideo:NO allowPickingImage:YES completion:^(NSArray<TZAssetModel *> *models) {
[tzImagePickerVc hideProgressHUD];
TZAssetModel *assetModel = [models firstObject];
BOOL isCrop = [self.cameraOptions sy_boolForKey:@"isCrop"];
BOOL showCropCircle = [self.cameraOptions sy_boolForKey:@"showCropCircle"];
NSInteger CropW = [self.cameraOptions sy_integerForKey:@"CropW"];
......@@ -226,7 +218,6 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options callback:(RCTResponseSender
TZImagePickerController *imagePicker = [[TZImagePickerController alloc] initCropTypeWithAsset:assetModel.asset photo:image completion:^(UIImage *cropImage, id asset) {
[self invokeSuccessWithResult:@[[self handleImageData:cropImage quality:quality]]];
}];
imagePicker.allowCrop = isCrop; // 裁剪
if(showCropCircle) {
imagePicker.needCircleCrop = showCropCircle; //圆形裁剪
......@@ -236,12 +227,10 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options callback:(RCTResponseSender
CGFloat y = ([[UIScreen mainScreen] bounds].size.height - CropH) / 2;
imagePicker.cropRect = CGRectMake(x,y,CropW,CropH);
}
[[self topViewController] presentViewController:imagePicker animated:YES completion:nil];
} else {
[self invokeSuccessWithResult:@[[self handleImageData:image quality:quality]]];
}
}];
}];
}
......@@ -257,7 +246,6 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options callback:(RCTResponseSender
}
#pragma mark - UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) { // 去设置界面,开启相机访问权限
if (iOS8Later) {
......@@ -273,13 +261,16 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options callback:(RCTResponseSender
photo[@"height"] = @(image.size.height);
NSString *fileName = [NSString stringWithFormat:@"%@.jpg", [[NSUUID UUID] UUIDString]];
NSString *filePath = [NSString stringWithFormat:@"%@/tmp/%@", NSHomeDirectory(), fileName];
[self createDir];
NSString *filePath = [NSString stringWithFormat:@"%@ImageCaches/%@", NSTemporaryDirectory(), fileName];
if ([UIImageJPEGRepresentation(image, quality/100) writeToFile:filePath atomically:YES]) {
photo[@"uri"] = filePath;
} else {
NSLog(@"保存压缩图片失败");
NSLog(@"保存压缩图片失败%@", filePath);
}
NSData *data = UIImageJPEGRepresentation(image, quality/100);
NSString *dataString = [data base64EncodedStringWithOptions:0]; // base64 encoded image string
photo[@"base64"] = dataString;
return photo;
}
......@@ -305,14 +296,23 @@ RCT_EXPORT_METHOD(openCamera:(NSDictionary *)options callback:(RCTResponseSender
}
}
- (BOOL)createDir {
NSString * path = [NSString stringWithFormat:@"%@ImageCaches", NSTemporaryDirectory()];;
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isDir;
if (![fileManager fileExistsAtPath:path isDirectory:&isDir]) {//先判断目录是否存在,不存在才创建
BOOL res=[fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil];
return res;
} else return NO;
}
- (UIViewController *)topViewController {
// UIViewController *rootViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController];
// UIViewController *rootViewController = [[[UIApplication sharedApplication] keyWindow] rootViewController];
UIViewController *rootViewController = RCTPresentedViewController();
return rootViewController;
}
- (dispatch_queue_t)methodQueue
{
- (dispatch_queue_t)methodQueue {
return dispatch_get_main_queue();
}
......
......@@ -23,19 +23,9 @@
}
+ (NSString *)tz_localizedStringForKey:(NSString *)key value:(NSString *)value {
static NSBundle *bundle = nil;
if (bundle == nil) {
NSString *language = [NSLocale preferredLanguages].firstObject;
if ([language rangeOfString:@"zh-Hans"].location != NSNotFound) {
language = @"zh-Hans";
} else if ([language rangeOfString:@"zh-Hant"].location != NSNotFound) {
language = @"zh-Hant";
} else {
language = @"en";
}
bundle = [NSBundle bundleWithPath:[[NSBundle tz_imagePickerBundle] pathForResource:language ofType:@"lproj"]];
}
NSBundle *bundle = [TZImagePickerConfig sharedInstance].languageBundle;
NSString *value1 = [bundle localizedStringForKey:key value:value table:nil];
return value1;
}
@end
......@@ -46,4 +46,6 @@ typedef enum : NSUInteger {
@property (nonatomic, assign) BOOL isCameraRoll;
- (void)setResult:(id)result needFetchAssets:(BOOL)needFetchAssets;
@end
......@@ -31,16 +31,16 @@
@implementation TZAlbumModel
- (void)setResult:(id)result {
- (void)setResult:(id)result needFetchAssets:(BOOL)needFetchAssets {
_result = result;
BOOL allowPickingImage = [[[NSUserDefaults standardUserDefaults] objectForKey:@"tz_allowPickingImage"] isEqualToString:@"1"];
BOOL allowPickingVideo = [[[NSUserDefaults standardUserDefaults] objectForKey:@"tz_allowPickingVideo"] isEqualToString:@"1"];
[[TZImageManager manager] getAssetsFromFetchResult:result allowPickingVideo:allowPickingVideo allowPickingImage:allowPickingImage completion:^(NSArray<TZAssetModel *> *models) {
_models = models;
if (_selectedModels) {
[self checkSelectedModels];
}
}];
if (needFetchAssets) {
[[TZImageManager manager] getAssetsFromFetchResult:result completion:^(NSArray<TZAssetModel *> *models) {
_models = models;
if (_selectedModels) {
[self checkSelectedModels];
}
}];
}
}
- (void)setSelectedModels:(NSArray *)selectedModels {
......
......@@ -10,6 +10,7 @@
#import "UIView+Layout.h"
#import <ImageIO/ImageIO.h>
#import "TZImageManager.h"
#import "TZImagePickerController.h"
@implementation TZImageCropManager
......@@ -131,17 +132,21 @@
animatedImage = [[UIImage alloc] initWithData:data];
}
else {
// images数组过大时内存会飙升,在这里限制下最大count
NSInteger maxCount = [TZImagePickerConfig sharedInstance].gifPreviewMaxImagesCount ?: 200;
NSInteger interval = MAX((count + maxCount / 2) / maxCount, 1);
NSMutableArray *images = [NSMutableArray array];
NSTimeInterval duration = 0.0f;
for (size_t i = 0; i < count; i++) {
for (size_t i = 0; i < count; i+=interval) {
CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
if (!image) {
continue;
}
duration += [self sd_frameDurationAtIndex:i source:source];
duration += [self sd_frameDurationAtIndex:i source:source] * MIN(interval, 3);
[images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
......
......@@ -21,7 +21,7 @@
+ (instancetype)manager NS_SWIFT_NAME(default());
+ (void)deallocManager;
@property (assign, nonatomic) id<TZImagePickerControllerDelegate> pickerDelegate;
@property (weak, nonatomic) id<TZImagePickerControllerDelegate> pickerDelegate;
@property (nonatomic, assign) BOOL shouldFixOrientation;
......@@ -50,10 +50,11 @@
- (void)requestAuthorizationWithCompletion:(void (^)(void))completion;
/// Get Album 获得相册/相册数组
- (void)getCameraRollAlbum:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage completion:(void (^)(TZAlbumModel *model))completion;
- (void)getAllAlbums:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage completion:(void (^)(NSArray<TZAlbumModel *> *models))completion;
- (void)getCameraRollAlbum:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage needFetchAssets:(BOOL)needFetchAssets completion:(void (^)(TZAlbumModel *model))completion;
- (void)getAllAlbums:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage needFetchAssets:(BOOL)needFetchAssets completion:(void (^)(NSArray<TZAlbumModel *> *models))completion;
/// Get Assets 获得Asset数组
- (void)getAssetsFromFetchResult:(id)result completion:(void (^)(NSArray<TZAssetModel *> *models))completion;
- (void)getAssetsFromFetchResult:(id)result allowPickingVideo:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage completion:(void (^)(NSArray<TZAssetModel *> *models))completion;
- (void)getAssetFromFetchResult:(id)result atIndex:(NSInteger)index allowPickingVideo:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage completion:(void (^)(TZAssetModel *model))completion;
......@@ -105,6 +106,9 @@
/// 获取asset的资源类型
- (TZAssetModelMediaType)getAssetType:(id)asset;
/// 缩放图片至新尺寸
- (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)size;
@end
//@interface TZSortDescriptor : NSSortDescriptor
......
......@@ -121,7 +121,7 @@ static dispatch_once_t onceToken;
#pragma mark - Get Album
/// Get Album 获得相册/相册数组
- (void)getCameraRollAlbum:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage completion:(void (^)(TZAlbumModel *))completion{
- (void)getCameraRollAlbum:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage needFetchAssets:(BOOL)needFetchAssets completion:(void (^)(TZAlbumModel *model))completion {
__block TZAlbumModel *model;
if (iOS8Later) {
PHFetchOptions *option = [[PHFetchOptions alloc] init];
......@@ -136,9 +136,11 @@ static dispatch_once_t onceToken;
for (PHAssetCollection *collection in smartAlbums) {
// 有可能是PHCollectionList类的的对象,过滤掉
if (![collection isKindOfClass:[PHAssetCollection class]]) continue;
// 过滤空相册
if (collection.estimatedAssetCount <= 0) continue;
if ([self isCameraRollAlbum:collection]) {
PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:option];
model = [self modelWithResult:fetchResult name:collection.localizedTitle isCameraRoll:YES];
model = [self modelWithResult:fetchResult name:collection.localizedTitle isCameraRoll:YES needFetchAssets:needFetchAssets];
if (completion) completion(model);
break;
}
......@@ -148,7 +150,7 @@ static dispatch_once_t onceToken;
if ([group numberOfAssets] < 1) return;
if ([self isCameraRollAlbum:group]) {
NSString *name = [group valueForProperty:ALAssetsGroupPropertyName];
model = [self modelWithResult:group name:name isCameraRoll:YES];
model = [self modelWithResult:group name:name isCameraRoll:YES needFetchAssets:needFetchAssets];
if (completion) completion(model);
*stop = YES;
}
......@@ -156,7 +158,7 @@ static dispatch_once_t onceToken;
}
}
- (void)getAllAlbums:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage completion:(void (^)(NSArray<TZAlbumModel *> *))completion{
- (void)getAllAlbums:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage needFetchAssets:(BOOL)needFetchAssets completion:(void (^)(NSArray<TZAlbumModel *> *))completion{
NSMutableArray *albumArr = [NSMutableArray array];
if (iOS8Later) {
PHFetchOptions *option = [[PHFetchOptions alloc] init];
......@@ -178,6 +180,8 @@ static dispatch_once_t onceToken;
for (PHAssetCollection *collection in fetchResult) {
// 有可能是PHCollectionList类的的对象,过滤掉
if (![collection isKindOfClass:[PHAssetCollection class]]) continue;
// 过滤空相册
if (collection.estimatedAssetCount <= 0) continue;
PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:collection options:option];
if (fetchResult.count < 1) continue;
......@@ -190,9 +194,9 @@ 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 ([self isCameraRollAlbum:collection]) {
[albumArr insertObject:[self modelWithResult:fetchResult name:collection.localizedTitle isCameraRoll:YES] atIndex:0];
[albumArr insertObject:[self modelWithResult:fetchResult name:collection.localizedTitle isCameraRoll:YES needFetchAssets:needFetchAssets] atIndex:0];
} else {
[albumArr addObject:[self modelWithResult:fetchResult name:collection.localizedTitle isCameraRoll:NO]];
[albumArr addObject:[self modelWithResult:fetchResult name:collection.localizedTitle isCameraRoll:NO needFetchAssets:needFetchAssets]];
}
}
}
......@@ -212,15 +216,15 @@ static dispatch_once_t onceToken;
}
if ([self isCameraRollAlbum:group]) {
[albumArr insertObject:[self modelWithResult:group name:name isCameraRoll:YES] atIndex:0];
[albumArr insertObject:[self modelWithResult:group name:name isCameraRoll:YES needFetchAssets:needFetchAssets] atIndex:0];
} else if ([name isEqualToString:@"My Photo Stream"] || [name isEqualToString:@"我的照片流"]) {
if (albumArr.count) {
[albumArr insertObject:[self modelWithResult:group name:name isCameraRoll:NO] atIndex:1];
[albumArr insertObject:[self modelWithResult:group name:name isCameraRoll:NO needFetchAssets:needFetchAssets] atIndex:1];
} else {
[albumArr addObject:[self modelWithResult:group name:name isCameraRoll:NO]];
[albumArr addObject:[self modelWithResult:group name:name isCameraRoll:NO needFetchAssets:needFetchAssets]];
}
} else {
[albumArr addObject:[self modelWithResult:group name:name isCameraRoll:NO]];
[albumArr addObject:[self modelWithResult:group name:name isCameraRoll:NO needFetchAssets:needFetchAssets]];
}
} failureBlock:nil];
}
......@@ -229,6 +233,11 @@ static dispatch_once_t onceToken;
#pragma mark - Get Assets
/// Get Assets 获得照片数组
- (void)getAssetsFromFetchResult:(id)result completion:(void (^)(NSArray<TZAssetModel *> *))completion {
TZImagePickerConfig *config = [TZImagePickerConfig sharedInstance];
return [self getAssetsFromFetchResult:result allowPickingVideo:config.allowPickingVideo allowPickingImage:config.allowPickingImage completion:completion];
}
- (void)getAssetsFromFetchResult:(id)result allowPickingVideo:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage completion:(void (^)(NSArray<TZAssetModel *> *))completion {
NSMutableArray *photoArr = [NSMutableArray array];
if ([result isKindOfClass:[PHFetchResult class]]) {
......@@ -606,7 +615,8 @@ static dispatch_once_t onceToken;
if ([asset isKindOfClass:[PHAsset class]]) {
PHImageRequestOptions *option = [[PHImageRequestOptions alloc] init];
option.networkAccessAllowed = YES;
option.resizeMode = PHImageRequestOptionsResizeModeFast;
option.version = PHImageRequestOptionsVersionOriginal;
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]);
if (downloadFinined && imageData) {
......@@ -650,7 +660,7 @@ static dispatch_once_t onceToken;
request.creationDate = [NSDate date];
}
} completionHandler:^(BOOL success, NSError *error) {
dispatch_sync(dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_main_queue(), ^{
if (success && completion) {
completion(nil);
} else if (error) {
......@@ -897,9 +907,9 @@ static dispatch_once_t onceToken;
#pragma mark - Private Method
- (TZAlbumModel *)modelWithResult:(id)result name:(NSString *)name isCameraRoll:(BOOL)isCameraRoll {
- (TZAlbumModel *)modelWithResult:(id)result name:(NSString *)name isCameraRoll:(BOOL)isCameraRoll needFetchAssets:(BOOL)needFetchAssets {
TZAlbumModel *model = [[TZAlbumModel alloc] init];
model.result = result;
[model setResult:result needFetchAssets:needFetchAssets];
model.name = name;
model.isCameraRoll = isCameraRoll;
if ([result isKindOfClass:[PHFetchResult class]]) {
......@@ -912,6 +922,7 @@ static dispatch_once_t onceToken;
return model;
}
/// 缩放图片至新尺寸
- (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)size {
if (image.size.width > size.width) {
UIGraphicsBeginImageContext(size);
......@@ -919,6 +930,19 @@ static dispatch_once_t onceToken;
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
/* 好像不怎么管用:https://mp.weixin.qq.com/s/CiqMlEIp1Ir2EJSDGgMooQ
CGFloat maxPixelSize = MAX(size.width, size.height);
CGImageSourceRef sourceRef = CGImageSourceCreateWithData((__bridge CFDataRef)UIImageJPEGRepresentation(image, 0.9), nil);
NSDictionary *options = @{(__bridge id)kCGImageSourceCreateThumbnailFromImageAlways:(__bridge id)kCFBooleanTrue,
(__bridge id)kCGImageSourceThumbnailMaxPixelSize:[NSNumber numberWithFloat:maxPixelSize]
};
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(sourceRef, 0, (__bridge CFDictionaryRef)options);
UIImage *newImage = [UIImage imageWithCGImage:imageRef scale:2 orientation:image.imageOrientation];
CGImageRelease(imageRef);
CFRelease(sourceRef);
return newImage;
*/
} else {
return image;
}
......
......@@ -4,7 +4,7 @@
//
// Created by 谭真 on 15/12/24.
// Copyright © 2015年 谭真. All rights reserved.
// version 1.9.8 - 2017.12.19
// version 2.0.0.9 - 2018.03.12
// 更多信息,请前往项目的github地址:https://github.com/banchichen/TZImagePickerController
/*
......@@ -28,6 +28,7 @@
@protocol TZImagePickerControllerDelegate;
@interface TZImagePickerController : UINavigationController
#pragma mark -
/// Use this init method / 用这个初始化方法
- (instancetype)initWithMaxImagesCount:(NSInteger)maxImagesCount delegate:(id<TZImagePickerControllerDelegate>)delegate;
- (instancetype)initWithMaxImagesCount:(NSInteger)maxImagesCount columnNumber:(NSInteger)columnNumber delegate:(id<TZImagePickerControllerDelegate>)delegate;
......@@ -37,6 +38,7 @@
/// This init method for crop photo / 用这个初始化方法以裁剪图片
- (instancetype)initCropTypeWithAsset:(id)asset photo:(UIImage *)photo completion:(void (^)(UIImage *cropImage,id asset))completion;
#pragma mark -
/// Default is 9 / 默认最大可选9张图片
@property (nonatomic, assign) NSInteger maxImagesCount;
......@@ -84,6 +86,14 @@
/// 默认为YES,如果设置为NO,拍照按钮将隐藏,用户将不能选择照片
@property(nonatomic, assign) BOOL allowTakePicture;
/// 首选语言,如果设置了就用该语言,不设则取当前系统语言。
/// 由于目前只支持中文、繁体中文、英文、越南语。故该属性只支持zh-Hans、zh-Hant、en、vi四种值,其余值无效。
@property (copy, nonatomic) NSString *preferredLanguage;
/// 语言bundle,preferredLanguage变化时languageBundle会变化
/// 可通过手动设置bundle,让选择器支持新的的语言(需要在设置preferredLanguage后设置languageBundle)。欢迎提交PR把语言文件提交上来~
@property (strong, nonatomic) NSBundle *languageBundle;
/// Default is YES, if set NO, user can't preview photo.
/// 默认为YES,如果设置为NO,预览按钮将隐藏,用户将不能去预览照片
@property (nonatomic, assign) BOOL allowPreview;
......@@ -92,6 +102,10 @@
/// 默认为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.
/// 默认为NO,如果设置为YES,代理方法里photos和infos会是nil,只返回assets
@property (assign, nonatomic) BOOL onlyReturnAsset;
/// The photos user have selected
/// 用户选中过的图片数组
@property (nonatomic, strong) NSMutableArray *selectedAssets;
......@@ -104,8 +118,12 @@
/// Hide the photo what can not be selected, Default is NO
/// 隐藏不可以选中的图片,默认是NO,不推荐将其设置为YES
@property (nonatomic, assign) BOOL hideWhenCanNotSelect;
/// 顶部statusBar 是否为系统默认的黑色,默认为NO
@property (nonatomic, assign) BOOL isStatusBarDefault;
/// Deprecated, Use statusBarStyle (顶部statusBar 是否为系统默认的黑色,默认为NO)
@property (nonatomic, assign) BOOL isStatusBarDefault __attribute__((deprecated("Use -statusBarStyle.")));
/// statusBar的样式,默认为UIStatusBarStyleLightContent
@property (assign, nonatomic) UIStatusBarStyle statusBarStyle;
#pragma mark -
/// Single selection mode, valid when maxImagesCount = 1
/// 单选模式,maxImagesCount为1时才生效
@property (nonatomic, assign) BOOL showSelectBtn; ///< 在单选模式下,照片列表页中,显示选择按钮,默认为NO
......@@ -119,6 +137,7 @@
@property (nonatomic, copy) void (^navLeftBarButtonSettingBlock)(UIButton *leftButton); ///< 自定义返回按钮样式及其属性
#pragma mark -
- (id)showAlertWithTitle:(NSString *)title;
- (void)hideAlertView:(id)alertView;
- (void)showProgressHUD;
......@@ -126,6 +145,7 @@
@property (nonatomic, assign) BOOL isSelectOriginalPhoto;
@property (assign, nonatomic) BOOL needShowStatusBar;
#pragma mark -
@property (nonatomic, copy) NSString *takePictureImageName;
@property (nonatomic, copy) NSString *photoSelImageName;
@property (nonatomic, copy) NSString *photoDefImageName;
......@@ -134,6 +154,7 @@
@property (nonatomic, copy) NSString *photoPreviewOriginDefImageName;
@property (nonatomic, copy) NSString *photoNumberIconImageName;
#pragma mark -
/// Appearance / 外观颜色 + 按钮文字
@property (nonatomic, strong) UIColor *oKButtonTitleColorNormal;
@property (nonatomic, strong) UIColor *oKButtonTitleColorDisabled;
......@@ -150,7 +171,7 @@
@property (nonatomic, copy) NSString *settingBtnTitleStr;
@property (nonatomic, copy) NSString *processHintStr;
/// Public Method
#pragma mark -
- (void)cancelButtonClick;
// The picker should dismiss itself; when it dismissed these handle will be called.
......@@ -221,6 +242,7 @@
@interface TZAlbumPickerController : UIViewController
@property (nonatomic, assign) NSInteger columnNumber;
@property (assign, nonatomic) BOOL isFirstAppear;
- (void)configTableView;
@end
......@@ -239,5 +261,17 @@
@interface TZCommonTools : NSObject
+ (BOOL)tz_isIPhoneX;
+ (CGFloat)tz_statusBarHeight;
// 获得Info.plist数据字典
+ (NSDictionary *)tz_getInfoDictionary;
@end
@interface TZImagePickerConfig : NSObject
+ (instancetype)sharedInstance;
@property (copy, nonatomic) NSString *preferredLanguage;
@property(nonatomic, assign) BOOL allowPickingImage;
@property (nonatomic, assign) BOOL allowPickingVideo;
@property (strong, nonatomic) NSBundle *languageBundle;
/// 默认是200,如果一个GIF过大,里面图片个数可能超过1000,会导致内存飙升而崩溃
@property (assign, nonatomic) NSInteger gifPreviewMaxImagesCount;
@end
......@@ -4,7 +4,7 @@
//
// Created by 谭真 on 15/12/24.
// Copyright © 2015年 谭真. All rights reserved.
// version 1.9.8 - 2017.12.19
// version 2.0.0.9 - 2018.03.12
// 更多信息,请前往项目的github地址:https://github.com/banchichen/TZImagePickerController
#import "TZImagePickerController.h"
......@@ -106,9 +106,19 @@
[self configBarButtonItemAppearance];
}
- (void)setIsStatusBarDefault:(BOOL)isStatusBarDefault {
_isStatusBarDefault = isStatusBarDefault;
if (isStatusBarDefault) {
self.statusBarStyle = iOS7Later ? UIStatusBarStyleDefault : UIStatusBarStyleBlackOpaque;
} else {
self.statusBarStyle = iOS7Later ? UIStatusBarStyleLightContent : UIStatusBarStyleBlackOpaque;
}
}
- (void)configBarButtonItemAppearance {
UIBarButtonItem *barItem;
if (@available(iOS 9.0, *)) {
if (iOS9Later) {
barItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[TZImagePickerController class]]];
} else {
barItem = [UIBarButtonItem appearanceWhenContainedIn:[TZImagePickerController class], nil];
......@@ -122,12 +132,7 @@
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
_originStatusBarStyle = [UIApplication sharedApplication].statusBarStyle;
if (self.isStatusBarDefault) {
[UIApplication sharedApplication].statusBarStyle = iOS7Later ? UIStatusBarStyleDefault : UIStatusBarStyleBlackOpaque;
} else {
[UIApplication sharedApplication].statusBarStyle = iOS7Later ? UIStatusBarStyleLightContent : UIStatusBarStyleBlackOpaque;
}
[UIApplication sharedApplication].statusBarStyle = self.statusBarStyle;
}
- (void)viewWillDisappear:(BOOL)animated {
......@@ -136,6 +141,10 @@
[self hideProgressHUD];
}
- (UIStatusBarStyle)preferredStatusBarStyle {
return self.statusBarStyle;
}
- (instancetype)initWithMaxImagesCount:(NSInteger)maxImagesCount delegate:(id<TZImagePickerControllerDelegate>)delegate {
return [self initWithMaxImagesCount:maxImagesCount columnNumber:4 delegate:delegate pushPhotoPickerVc:YES];
}
......@@ -147,6 +156,7 @@
- (instancetype)initWithMaxImagesCount:(NSInteger)maxImagesCount columnNumber:(NSInteger)columnNumber delegate:(id<TZImagePickerControllerDelegate>)delegate pushPhotoPickerVc:(BOOL)pushPhotoPickerVc {
_pushPhotoPickerVc = pushPhotoPickerVc;
TZAlbumPickerController *albumPickerVc = [[TZAlbumPickerController alloc] init];
albumPickerVc.isFirstAppear = YES;
albumPickerVc.columnNumber = columnNumber;
self = [super initWithRootViewController:albumPickerVc];
if (self) {
......@@ -172,10 +182,8 @@
_tipLabel.numberOfLines = 0;
_tipLabel.font = [UIFont systemFontOfSize:16];
_tipLabel.textColor = [UIColor blackColor];
NSDictionary *infoDict = [NSBundle mainBundle].localizedInfoDictionary;
if (!infoDict || !infoDict.count) {
infoDict = [NSBundle mainBundle].infoDictionary;
}
NSDictionary *infoDict = [TZCommonTools tz_getInfoDictionary];
NSString *appName = [infoDict valueForKey:@"CFBundleDisplayName"];
if (!appName) appName = [infoDict valueForKey:@"CFBundleName"];
NSString *tipText = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Allow %@ to access your album in \"Settings -> Privacy -> Photos\""],appName];
......@@ -191,7 +199,9 @@
[self.view addSubview:_settingBtn];
}
_timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(observeAuthrizationStatusChange) userInfo:nil repeats:YES];
if ([TZImageManager authorizationStatus] == 0) {
_timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(observeAuthrizationStatusChange) userInfo:nil repeats:NO];
}
} else {
[self pushPhotoPickerVc];
}
......@@ -259,6 +269,7 @@
self.barItemTextFont = [UIFont systemFontOfSize:15];
self.barItemTextColor = [UIColor whiteColor];
self.allowPreview = YES;
self.statusBarStyle = UIStatusBarStyleLightContent;
[self configDefaultImageName];
[self configDefaultBtnTitle];
......@@ -287,12 +298,22 @@
}
- (void)observeAuthrizationStatusChange {
[_timer invalidate];
_timer = nil;
if ([TZImageManager authorizationStatus] == 0) {
_timer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(observeAuthrizationStatusChange) userInfo:nil repeats:NO];
}
if ([[TZImageManager manager] authorizationStatusAuthorized]) {
[_tipLabel removeFromSuperview];
[_settingBtn removeFromSuperview];
[_timer invalidate];
_timer = nil;
[self pushPhotoPickerVc];
TZAlbumPickerController *albumPickerVc = (TZAlbumPickerController *)self.visibleViewController;
if ([albumPickerVc isKindOfClass:[TZAlbumPickerController class]]) {
[albumPickerVc configTableView];
}
}
}
......@@ -303,17 +324,12 @@
TZPhotoPickerController *photoPickerVc = [[TZPhotoPickerController alloc] init];
photoPickerVc.isFirstAppear = YES;
photoPickerVc.columnNumber = self.columnNumber;
[[TZImageManager manager] getCameraRollAlbum:self.allowPickingVideo allowPickingImage:self.allowPickingImage completion:^(TZAlbumModel *model) {
[[TZImageManager manager] getCameraRollAlbum:self.allowPickingVideo allowPickingImage:self.allowPickingImage needFetchAssets:NO completion:^(TZAlbumModel *model) {
photoPickerVc.model = model;
[self pushViewController:photoPickerVc animated:YES];
_didPushPhotoPickerVc = YES;
}];
}
TZAlbumPickerController *albumPickerVc = (TZAlbumPickerController *)self.visibleViewController;
if ([albumPickerVc isKindOfClass:[TZAlbumPickerController class]]) {
[albumPickerVc configTableView];
}
}
- (id)showAlertWithTitle:(NSString *)title {
......@@ -486,16 +502,24 @@
- (void)setAllowPickingImage:(BOOL)allowPickingImage {
_allowPickingImage = allowPickingImage;
NSString *allowPickingImageStr = _allowPickingImage ? @"1" : @"0";
[[NSUserDefaults standardUserDefaults] setObject:allowPickingImageStr forKey:@"tz_allowPickingImage"];
[[NSUserDefaults standardUserDefaults] synchronize];
[TZImagePickerConfig sharedInstance].allowPickingImage = allowPickingImage;
}
- (void)setAllowPickingVideo:(BOOL)allowPickingVideo {
_allowPickingVideo = allowPickingVideo;
NSString *allowPickingVideoStr = _allowPickingVideo ? @"1" : @"0";
[[NSUserDefaults standardUserDefaults] setObject:allowPickingVideoStr forKey:@"tz_allowPickingVideo"];
[[NSUserDefaults standardUserDefaults] synchronize];
[TZImagePickerConfig sharedInstance].allowPickingVideo = allowPickingVideo;
}
- (void)setPreferredLanguage:(NSString *)preferredLanguage {
_preferredLanguage = preferredLanguage;
[TZImagePickerConfig sharedInstance].preferredLanguage = preferredLanguage;
[self configDefaultBtnTitle];
}
- (void)setLanguageBundle:(NSBundle *)languageBundle {
_languageBundle = languageBundle;
[TZImagePickerConfig sharedInstance].languageBundle = languageBundle;
[self configDefaultBtnTitle];
}
- (void)setSortAscendingByModificationDate:(BOOL)sortAscendingByModificationDate {
......@@ -508,8 +532,9 @@
}
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (iOS7Later) viewController.automaticallyAdjustsScrollViewInsets = NO;
if (_timer) { [_timer invalidate]; _timer = nil;}
if (iOS7Later) {
viewController.automaticallyAdjustsScrollViewInsets = NO;
}
[super pushViewController:viewController animated:animated];
}
......@@ -583,7 +608,6 @@
UITableView *_tableView;
}
@property (nonatomic, strong) NSMutableArray *albumArr;
@property (assign, nonatomic) BOOL isFirstAppear;
@end
@implementation TZAlbumPickerController
......@@ -609,21 +633,36 @@
if (self.isFirstAppear && !imagePickerVc.navLeftBarButtonSettingBlock) {
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:[NSBundle tz_localizedStringForKey:@"Back"] style:UIBarButtonItemStylePlain target:nil action:nil];
self.isFirstAppear = NO;
}
[self configTableView];
}
- (void)configTableView {
if (![[TZImageManager manager] authorizationStatusAuthorized]) {
return;
}
if (self.isFirstAppear) {
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
[imagePickerVc showProgressHUD];
}
dispatch_async(dispatch_get_global_queue(0, 0), ^{
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
[[TZImageManager manager] getAllAlbums:imagePickerVc.allowPickingVideo allowPickingImage:imagePickerVc.allowPickingImage completion:^(NSArray<TZAlbumModel *> *models) {
[[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) {
albumModel.selectedModels = imagePickerVc.selectedModels;
}
[imagePickerVc hideProgressHUD];
if (self.isFirstAppear) {
self.isFirstAppear = NO;
[self configTableView];
}
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
_tableView.rowHeight = 70;
......@@ -757,4 +796,52 @@
return [self tz_isIPhoneX] ? 44 : 20;
}
// 获得Info.plist数据字典
+ (NSDictionary *)tz_getInfoDictionary {
NSDictionary *infoDict = [NSBundle mainBundle].localizedInfoDictionary;
if (!infoDict || !infoDict.count) {
infoDict = [NSBundle mainBundle].infoDictionary;
}
if (!infoDict || !infoDict.count) {
NSString *path = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
infoDict = [NSDictionary dictionaryWithContentsOfFile:path];
}
return infoDict ? infoDict : @{};
}
@end
@implementation TZImagePickerConfig
+ (instancetype)sharedInstance {
static dispatch_once_t onceToken;
static TZImagePickerConfig *config = nil;
dispatch_once(&onceToken, ^{
if (config == nil) {
config = [[TZImagePickerConfig alloc] init];
config.preferredLanguage = nil;
config.gifPreviewMaxImagesCount = 200;
}
});
return config;
}
- (void)setPreferredLanguage:(NSString *)preferredLanguage {
_preferredLanguage = preferredLanguage;
if (!preferredLanguage || !preferredLanguage.length) {
preferredLanguage = [NSLocale preferredLanguages].firstObject;
}
if ([preferredLanguage rangeOfString:@"zh-Hans"].location != NSNotFound) {
preferredLanguage = @"zh-Hans";
} else if ([preferredLanguage rangeOfString:@"zh-Hant"].location != NSNotFound) {
preferredLanguage = @"zh-Hant";
} else if ([preferredLanguage rangeOfString:@"vi"].location != NSNotFound) {
preferredLanguage = @"vi";
} else {
preferredLanguage = @"en";
}
_languageBundle = [NSBundle bundleWithPath:[[NSBundle tz_imagePickerBundle] pathForResource:preferredLanguage ofType:@"lproj"]];
}
@end
......@@ -16,9 +16,9 @@
/// 开始定位
- (void)startLocation;
- (void)startLocationWithSuccessBlock:(void (^)(CLLocation *location,CLLocation *oldLocation))successBlock failureBlock:(void (^)(NSError *error))failureBlock;
- (void)startLocationWithSuccessBlock:(void (^)(NSArray<CLLocation *> *))successBlock failureBlock:(void (^)(NSError *error))failureBlock;
- (void)startLocationWithGeocoderBlock:(void (^)(NSArray *geocoderArray))geocoderBlock;
- (void)startLocationWithSuccessBlock:(void (^)(CLLocation *location,CLLocation *oldLocation))successBlock failureBlock:(void (^)(NSError *error))failureBlock geocoderBlock:(void (^)(NSArray *geocoderArray))geocoderBlock;
- (void)startLocationWithSuccessBlock:(void (^)(NSArray<CLLocation *> *))successBlock failureBlock:(void (^)(NSError *error))failureBlock geocoderBlock:(void (^)(NSArray *geocoderArray))geocoderBlock;
@end
......@@ -12,7 +12,7 @@
@interface TZLocationManager ()<CLLocationManagerDelegate>
@property (nonatomic, strong) CLLocationManager *locationManager;
/// 定位成功的回调block
@property (nonatomic, copy) void (^successBlock)(CLLocation *location,CLLocation *oldLocation);
@property (nonatomic, copy) void (^successBlock)(NSArray<CLLocation *> *);
/// 编码成功的回调block
@property (nonatomic, copy) void (^geocodeBlock)(NSArray *geocodeArray);
/// 定位失败的回调block
......@@ -39,7 +39,7 @@
[self startLocationWithSuccessBlock:nil failureBlock:nil geocoderBlock:nil];
}
- (void)startLocationWithSuccessBlock:(void (^)(CLLocation *location,CLLocation *oldLocation))successBlock failureBlock:(void (^)(NSError *error))failureBlock {
- (void)startLocationWithSuccessBlock:(void (^)(NSArray<CLLocation *> *))successBlock failureBlock:(void (^)(NSError *error))failureBlock {
[self startLocationWithSuccessBlock:successBlock failureBlock:failureBlock geocoderBlock:nil];
}
......@@ -47,7 +47,7 @@
[self startLocationWithSuccessBlock:nil failureBlock:nil geocoderBlock:geocoderBlock];
}
- (void)startLocationWithSuccessBlock:(void (^)(CLLocation *location,CLLocation *oldLocation))successBlock failureBlock:(void (^)(NSError *error))failureBlock geocoderBlock:(void (^)(NSArray *geocoderArray))geocoderBlock {
- (void)startLocationWithSuccessBlock:(void (^)(NSArray<CLLocation *> *))successBlock failureBlock:(void (^)(NSError *error))failureBlock geocoderBlock:(void (^)(NSArray *geocoderArray))geocoderBlock {
[self.locationManager startUpdatingLocation];
_successBlock = successBlock;
_geocodeBlock = geocoderBlock;
......@@ -57,16 +57,16 @@
#pragma mark - CLLocationManagerDelegate
/// 地理位置发生改变时触发
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
[manager stopUpdatingLocation];
if (_successBlock) {
_successBlock(newLocation,oldLocation);
_successBlock(locations);
}
if (_geocodeBlock) {
if (_geocodeBlock && locations.count) {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *array, NSError *error) {
[geocoder reverseGeocodeLocation:[locations firstObject] completionHandler:^(NSArray *array, NSError *error) {
_geocodeBlock(array);
}];
}
......
......@@ -59,7 +59,7 @@ static CGFloat itemMargin = 5;
}
_imagePickerVc.navigationBar.tintColor = self.navigationController.navigationBar.tintColor;
UIBarButtonItem *tzBarItem, *BarItem;
if (@available(iOS 9.0, *)) {
if (iOS9Later) {
tzBarItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[TZImagePickerController class]]];
BarItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UIImagePickerController class]]];
} else {
......@@ -73,6 +73,7 @@ static CGFloat itemMargin = 5;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.isFirstAppear = YES;
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
_isSelectOriginalPhoto = tzImagePickerVc.isSelectOriginalPhoto;
_shouldScrollToBottom = YES;
......@@ -93,19 +94,19 @@ static CGFloat itemMargin = 5;
- (void)fetchAssetModels {
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (_isFirstAppear) {
if (_isFirstAppear && !_model.models.count) {
[tzImagePickerVc showProgressHUD];
}
dispatch_sync(dispatch_get_global_queue(0, 0), ^{
if (!tzImagePickerVc.sortAscendingByModificationDate && _isFirstAppear && iOS8Later) {
[[TZImageManager manager] getCameraRollAlbum:tzImagePickerVc.allowPickingVideo allowPickingImage:tzImagePickerVc.allowPickingImage completion:^(TZAlbumModel *model) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
if (!tzImagePickerVc.sortAscendingByModificationDate && _isFirstAppear && iOS8Later && _model.isCameraRoll) {
[[TZImageManager manager] getCameraRollAlbum:tzImagePickerVc.allowPickingVideo allowPickingImage:tzImagePickerVc.allowPickingImage needFetchAssets:YES completion:^(TZAlbumModel *model) {
_model = model;
_models = [NSMutableArray arrayWithArray:_model.models];
[self initSubviews];
}];
} else {
if (_showTakePhotoBtn || !iOS8Later || _isFirstAppear) {
[[TZImageManager manager] getAssetsFromFetchResult:_model.result allowPickingVideo:tzImagePickerVc.allowPickingVideo allowPickingImage:tzImagePickerVc.allowPickingImage completion:^(NSArray<TZAssetModel *> *models) {
[[TZImageManager manager] getAssetsFromFetchResult:_model.result completion:^(NSArray<TZAssetModel *> *models) {
_models = [NSMutableArray arrayWithArray:models];
[self initSubviews];
}];
......@@ -307,8 +308,9 @@ static CGFloat itemMargin = 5;
_originalPhotoButton.frame = CGRectMake(CGRectGetMaxX(_previewButton.frame), 0, fullImageWidth + 56, 50);
_originalPhotoLabel.frame = CGRectMake(fullImageWidth + 46, 0, 80, 50);
}
_doneButton.frame = CGRectMake(self.view.tz_width - 44 - 12, 3, 44, 44);
_numberImageView.frame = CGRectMake(self.view.tz_width - 56 - 28, 10, 30, 30);
[_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);
_numberLabel.frame = _numberImageView.frame;
_divideLine.frame = CGRectMake(0, 0, self.view.tz_width, 1);
......@@ -335,7 +337,9 @@ static CGFloat itemMargin = 5;
_originalPhotoButton.selected = !_originalPhotoButton.isSelected;
_isSelectOriginalPhoto = _originalPhotoButton.isSelected;
_originalPhotoLabel.hidden = !_originalPhotoButton.isSelected;
if (_isSelectOriginalPhoto) [self getSelectedPhotoBytes];
if (_isSelectOriginalPhoto) {
[self getSelectedPhotoBytes];
}
}
- (void)doneButtonClick {
......@@ -348,45 +352,54 @@ static CGFloat itemMargin = 5;
}
[tzImagePickerVc showProgressHUD];
NSMutableArray *photos = [NSMutableArray array];
NSMutableArray *assets = [NSMutableArray array];
NSMutableArray *infoArr = [NSMutableArray array];
for (NSInteger i = 0; i < tzImagePickerVc.selectedModels.count; i++) { [photos addObject:@1];[assets addObject:@1];[infoArr addObject:@1]; }
__block BOOL havenotShowAlert = YES;
[TZImageManager manager].shouldFixOrientation = YES;
__block id 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) {
if (isDegraded) return;
if (photo) {
photo = [self 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];
[assets replaceObjectAtIndex:i withObject:model.asset];
for (id item in photos) { if ([item isKindOfClass:[NSNumber class]]) return; }
if (havenotShowAlert) {
[tzImagePickerVc hideAlertView:alertView];
[self didGetAllPhotos:photos assets:assets infoArr:infoArr];
}
} progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
// 如果图片正在从iCloud同步中,提醒用户
if (progress < 1 && havenotShowAlert && !alertView) {
[tzImagePickerVc hideProgressHUD];
alertView = [tzImagePickerVc showAlertWithTitle:[NSBundle tz_localizedStringForKey:@"Synchronizing photos from iCloud"]];
havenotShowAlert = NO;
return;
}
if (progress >= 1) {
havenotShowAlert = YES;
}
} networkAccessAllowed:YES];
NSMutableArray *photos;
NSMutableArray *infoArr;
if (tzImagePickerVc.onlyReturnAsset) { // not fetch image
for (NSInteger i = 0; i < tzImagePickerVc.selectedModels.count; i++) {
TZAssetModel *model = tzImagePickerVc.selectedModels[i];
[assets addObject:model.asset];
}
} else { // fetch image
photos = [NSMutableArray array];
infoArr = [NSMutableArray array];
for (NSInteger i = 0; i < tzImagePickerVc.selectedModels.count; i++) { [photos addObject:@1];[assets addObject:@1];[infoArr addObject:@1]; }
__block BOOL havenotShowAlert = YES;
[TZImageManager manager].shouldFixOrientation = YES;
__block id 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) {
if (isDegraded) return;
if (photo) {
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];
[assets replaceObjectAtIndex:i withObject:model.asset];
for (id item in photos) { if ([item isKindOfClass:[NSNumber class]]) return; }
if (havenotShowAlert) {
[tzImagePickerVc hideAlertView:alertView];
[self didGetAllPhotos:photos assets:assets infoArr:infoArr];
}
} progressHandler:^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
// 如果图片正在从iCloud同步中,提醒用户
if (progress < 1 && havenotShowAlert && !alertView) {
[tzImagePickerVc hideProgressHUD];
alertView = [tzImagePickerVc showAlertWithTitle:[NSBundle tz_localizedStringForKey:@"Synchronizing photos from iCloud"]];
havenotShowAlert = NO;
return;
}
if (progress >= 1) {
havenotShowAlert = YES;
}
} networkAccessAllowed:YES];
}
}
if (tzImagePickerVc.selectedModels.count <= 0) {
if (tzImagePickerVc.selectedModels.count <= 0 || tzImagePickerVc.onlyReturnAsset) {
[self didGetAllPhotos:photos assets:assets infoArr:infoArr];
}
}
......@@ -545,9 +558,12 @@ static CGFloat itemMargin = 5;
- (void)takePhoto {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if ((authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied) && iOS7Later) {
NSDictionary *infoDict = [TZCommonTools tz_getInfoDictionary];
// 无权限 做一个友好的提示
NSString *appName = [[NSBundle mainBundle].infoDictionary valueForKey:@"CFBundleDisplayName"];
if (!appName) appName = [[NSBundle mainBundle].infoDictionary valueForKey:@"CFBundleName"];
NSString *appName = [infoDict valueForKey:@"CFBundleDisplayName"];
if (!appName) appName = [infoDict valueForKey:@"CFBundleName"];
NSString *message = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Please allow %@ to access your camera in \"Settings -> Privacy -> Camera\""],appName];
if (iOS8Later) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSBundle tz_localizedStringForKey:@"Can not use camera"] message:message delegate:self cancelButtonTitle:[NSBundle tz_localizedStringForKey:@"Cancel"] otherButtonTitles:[NSBundle tz_localizedStringForKey:@"Setting"], nil];
......@@ -561,7 +577,7 @@ static CGFloat itemMargin = 5;
if (iOS7Later) {
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted) {
dispatch_sync(dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[self pushImagePickerController];
});
}
......@@ -578,9 +594,9 @@ static CGFloat itemMargin = 5;
- (void)pushImagePickerController {
// 提前定位
__weak typeof(self) weakSelf = self;
[[TZLocationManager manager] startLocationWithSuccessBlock:^(CLLocation *location, CLLocation *oldLocation) {
[[TZLocationManager manager] startLocationWithSuccessBlock:^(NSArray<CLLocation *> *locations) {
__strong typeof(weakSelf) strongSelf = weakSelf;
strongSelf.location = location;
strongSelf.location = [locations firstObject];
} failureBlock:^(NSError *error) {
__strong typeof(weakSelf) strongSelf = weakSelf;
strongSelf.location = nil;
......@@ -636,24 +652,16 @@ static CGFloat itemMargin = 5;
}
- (void)getSelectedPhotoBytes {
// 越南语 && 5屏幕时会显示不下,暂时这样处理
if ([[TZImagePickerConfig sharedInstance].preferredLanguage isEqualToString:@"vi"] && self.view.tz_width <= 320) {
return;
}
TZImagePickerController *imagePickerVc = (TZImagePickerController *)self.navigationController;
[[TZImageManager manager] getPhotosBytesWithArray:imagePickerVc.selectedModels completion:^(NSString *totalBytes) {
_originalPhotoLabel.text = [NSString stringWithFormat:@"(%@)",totalBytes];
}];
}
/// Scale image / 缩放图片
- (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)size {
if (image.size.width < size.width) {
return image;
}
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
- (void)scrollCollectionViewToBottom {
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (_shouldScrollToBottom && _models.count > 0) {
......@@ -678,13 +686,13 @@ static CGFloat itemMargin = 5;
}
- (void)checkSelectedModels {
NSMutableArray *selectedAssets = [NSMutableArray array];
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
for (TZAssetModel *model in tzImagePickerVc.selectedModels) {
[selectedAssets addObject:model.asset];
}
for (TZAssetModel *model in _models) {
model.isSelected = NO;
NSMutableArray *selectedAssets = [NSMutableArray array];
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
for (TZAssetModel *model in tzImagePickerVc.selectedModels) {
[selectedAssets addObject:model.asset];
}
if ([[TZImageManager manager] isAssetsArray:selectedAssets containAsset:model.asset]) {
model.isSelected = YES;
}
......@@ -723,9 +731,9 @@ static CGFloat itemMargin = 5;
- (void)reloadPhotoArray {
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
[[TZImageManager manager] getCameraRollAlbum:tzImagePickerVc.allowPickingVideo allowPickingImage:tzImagePickerVc.allowPickingImage completion:^(TZAlbumModel *model) {
[[TZImageManager manager] getCameraRollAlbum:tzImagePickerVc.allowPickingVideo allowPickingImage:tzImagePickerVc.allowPickingImage needFetchAssets:NO completion:^(TZAlbumModel *model) {
_model = model;
[[TZImageManager manager] getAssetsFromFetchResult:_model.result allowPickingVideo:tzImagePickerVc.allowPickingVideo allowPickingImage:tzImagePickerVc.allowPickingImage completion:^(NSArray<TZAssetModel *> *models) {
[[TZImageManager manager] getAssetsFromFetchResult:_model.result completion:^(NSArray<TZAssetModel *> *models) {
[tzImagePickerVc hideProgressHUD];
TZAssetModel *assetModel;
......
......@@ -246,8 +246,9 @@
_originalPhotoButton.frame = CGRectMake(0, 0, fullImageWidth + 56, 44);
_originalPhotoLabel.frame = CGRectMake(fullImageWidth + 42, 0, 80, 44);
}
_doneButton.frame = CGRectMake(self.view.tz_width - 44 - 12, 0, 44, 44);
_numberImageView.frame = CGRectMake(self.view.tz_width - 56 - 28, 7, 30, 30);
[_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);
_numberLabel.frame = _numberImageView.frame;
[self configCropView];
......
......@@ -26,6 +26,7 @@
UIStatusBarStyle _originStatusBarStyle;
}
@property (assign, nonatomic) BOOL needShowStatusBar;
@end
#pragma clang diagnostic push
......@@ -35,6 +36,7 @@
- (void)viewDidLoad {
[super viewDidLoad];
self.needShowStatusBar = ![UIApplication sharedApplication].statusBarHidden;
self.view.backgroundColor = [UIColor blackColor];
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (tzImagePickerVc) {
......@@ -57,8 +59,8 @@
- (void)configMoviePlayer {
[[TZImageManager manager] getPhotoWithAsset:_model.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
_cover = photo;
if (!isDegraded && photo) {
_cover = photo;
_doneButton.enabled = YES;
}
}];
......@@ -104,7 +106,9 @@
_doneButton = [UIButton buttonWithType:UIButtonTypeCustom];
_doneButton.titleLabel.font = [UIFont systemFontOfSize:16];
_doneButton.enabled = NO;
if (!_cover) {
_doneButton.enabled = NO;
}
[_doneButton addTarget:self action:@selector(doneButtonClick) forControlEvents:UIControlEventTouchUpInside];
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (tzImagePickerVc) {
......@@ -185,8 +189,7 @@
[self.navigationController setNavigationBarHidden:NO];
[_playButton setImage:[UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlay"] forState:UIControlStateNormal];
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (tzImagePickerVc.needShowStatusBar && iOS7Later) {
if (self.needShowStatusBar && iOS7Later) {
[UIApplication sharedApplication].statusBarHidden = NO;
}
}
......
{
"name": "react-native-syan-image-picker",
"version": "0.1.0",
"version": "0.1.1",
"description": "",
"main": "index.js",
"scripts": {
......@@ -18,5 +18,5 @@
"Photo"
],
"author": "",
"license": ""
"license": "MIT"
}
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