123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- //
- // SelectImageHandler.m
- // Starbuds
- //
- // Created by 翟玉磊 on 2020/1/7.
- // Copyright © 2020 翟玉磊. All rights reserved.
- //
- #import "SelectImageHandler.h"
- #import <Photos/Photos.h>
- #import "BottomBasePopupController.h"
- @interface SelectImageHandler ()<UIImagePickerControllerDelegate,UIAlertViewDelegate, TZImagePickerControllerDelegate, UINavigationControllerDelegate>
- @property (nonatomic, strong) UIImagePickerController *imagePickerVc;
- @property (strong, nonatomic) CLLocation *location;
- @end
- @implementation SelectImageHandler
- - (instancetype)init {
- if (self = [super init]) {
- }
- return self;
- }
- #pragma mark — Public
- /// 显示图片选择控制器
- /// @param maxCount 能选择的最大数量
- /// @param parentController 父控制器且支持代理
- - (void)showImagePickerControllerWithMaxCount:(NSInteger)maxCount parentController:(UIViewController*)parentController; {
- self.maxImagesCount = maxCount;
- self.parentController = parentController;
- CustomActionSheetController *sheet = [[CustomActionSheetController alloc] initWithTitle:nil categoryTitles:@[kLocalizedString(@"拍照"), kLocalizedString(@"从手机相册选择")] cancel:kLocalizedString(@"取消") selctedBlock:^(NSInteger index, NSString * _Nonnull title) {
- if (index == 1) {
- [self takePhoto];
- }
- if (index == 2) {
- [self pushTZImagePickerController];
- }
- }];
- [sheet show];
- }
- /// 预览图片
- /// @param selectedPhotos 选中的图片数组
- /// @param selectedAssets 选中图片数组的相册数据
- /// @param index 选中的索引
- /// @param parentController 父控制器
- - (void)previewImagePickerWithSelectedPhotos:(NSArray *)selectedPhotos selectedAssets:(NSArray *)selectedAssets index:(NSInteger)index parentController:(UIViewController*)parentController {
- self.parentController = parentController;
-
- TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithSelectedAssets:[selectedAssets copy] selectedPhotos:[selectedPhotos copy] index:index];
- imagePickerVc.maxImagesCount = self.maxImagesCount;
- imagePickerVc.allowPickingOriginalPhoto = YES;
- imagePickerVc.showSelectedIndex = YES;
- imagePickerVc.modalPresentationStyle = UIModalPresentationFullScreen;
- [imagePickerVc setDidFinishPickingPhotosHandle:^(NSArray<UIImage *> *photos, NSArray *assets, BOOL isSelectOriginalPhoto) {
-
- if (self.delegate && [self.delegate respondsToSelector:@selector(previewImageDidFinishPhotos:sourceAssets:isSelectOriginalPhoto:)]) {
- [self.delegate previewImageDidFinishPhotos:photos sourceAssets:assets isSelectOriginalPhoto:isSelectOriginalPhoto];
- }
- }];
- [self.parentController presentViewController:imagePickerVc animated:YES completion:nil];
- }
- #pragma mark — 相机操作
- - (void)takePhoto {
- AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
- if (authStatus == AVAuthorizationStatusRestricted || authStatus == AVAuthorizationStatusDenied) {
- // 无相机权限 做一个友好的提示
- UIAlertController *al = [BlockAlertController alertWithTitle:kLocalizedString(@"无法使用相机") message:kLocalizedString(@"请在iPhone的""设置-隐私-相机""中允许访问相机") cancelTitle:kLocalizedString(@"取消") sureTitle:kLocalizedString(@"设置") clickAction:^(UIAlertAction *action) {
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
- }];
- [self.parentController presentViewController:al animated:YES completion:nil];
- } else if (authStatus == AVAuthorizationStatusNotDetermined) {
- // fix issue 466, 防止用户首次拍照拒绝授权时相机页黑屏
- [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
- if (granted) {
- dispatch_async(dispatch_get_main_queue(), ^{
- [self takePhoto];
- });
- }
- }];
- // 拍照之前还需要检查相册权限
- } else if ([PHPhotoLibrary authorizationStatus] == 2) { // 已被拒绝,没有相册权限,将无法保存拍的照片
- UIAlertController *al = [BlockAlertController alertWithTitle:kLocalizedString(@"无法使用相机") message:kLocalizedString(@"请在iPhone的""设置-隐私-相机""中允许访问相机") cancelTitle:kLocalizedString(@"取消") sureTitle:kLocalizedString(@"设置") clickAction:^(UIAlertAction *action) {
- if ([action.title isEqualToString:@"设置"]) {
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
- }
- }];
- [self.parentController presentViewController:al animated:YES completion:nil];
- } else if ([PHPhotoLibrary authorizationStatus] == 0) { // 未请求过相册权限
- [[TZImageManager manager] requestAuthorizationWithCompletion:^{
- [self takePhoto];
- }];
- } else {
- [self pushImagePickerController];
- }
- }
- // 调用相机
- - (void)pushImagePickerController {
- // 提前定位
- __weak typeof(self) weakSelf = self;
- [[TZLocationManager manager] startLocationWithSuccessBlock:^(NSArray<CLLocation *> *locations) {
- __strong typeof(weakSelf) strongSelf = weakSelf;
- strongSelf.location = [locations firstObject];
- } failureBlock:^(NSError *error) {
- __strong typeof(weakSelf) strongSelf = weakSelf;
- strongSelf.location = nil;
- }];
-
- UIImagePickerControllerSourceType sourceType = UIImagePickerControllerSourceTypeCamera;
- if ([UIImagePickerController isSourceTypeAvailable: UIImagePickerControllerSourceTypeCamera]) {
- self.imagePickerVc.sourceType = sourceType;
- [self.parentController presentViewController:_imagePickerVc animated:YES completion:nil];
- } else {
- NSLog(@"模拟器中无法打开照相机,请在真机中使用");
- }
- }
- #pragma mark - UIImagePickerController
- - (void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
- [picker dismissViewControllerAnimated:YES completion:nil];
- NSString *type = [info objectForKey:UIImagePickerControllerMediaType];
-
- TZImagePickerController *tzImagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:1 delegate:self];
- // 对照片排序,按修改时间升序,默认是YES
- tzImagePickerVc.sortAscendingByModificationDate = YES;
- [tzImagePickerVc showProgressHUD];
- if ([type isEqualToString:@"public.image"]) {
- UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
- // save photo and get asset / 保存图片,获取到asset
- [[TZImageManager manager] savePhotoWithImage:image location:self.location completion:^(PHAsset *asset, NSError *error) {
- [tzImagePickerVc hideProgressHUD];
- if (error) {
- NSLog(@"图片保存失败 %@",error);
- } else {
- TZAssetModel *assetModel = [[TZImageManager manager] createModelWithAsset:asset];
- if (self.allowCrop) { // 允许裁剪,去裁剪
- TZImagePickerController *imagePicker = [[TZImagePickerController alloc] initCropTypeWithAsset:assetModel.asset photo:image completion:^(UIImage *cropImage, id asset) {
- [self didFinishWithAddedAsset:asset image:cropImage];
- }];
- imagePicker.allowPickingImage = YES;
- imagePicker.needCircleCrop = self.needCircleCrop;
- imagePicker.circleCropRadius = 100;
- [self.parentController presentViewController:imagePicker animated:YES completion:nil];
- } else {
- [self didFinishWithAddedAsset:assetModel.asset image:image];
- }
- }
- }];
-
- } else if ([type isEqualToString:@"public.movie"]) {
- NSURL *videoUrl = [info objectForKey:UIImagePickerControllerMediaURL];
- if (videoUrl) {
- [[TZImageManager manager] saveVideoWithUrl:videoUrl location:self.location completion:^(PHAsset *asset, NSError *error) {
- [tzImagePickerVc hideProgressHUD];
- if (!error) {
- TZAssetModel *assetModel = [[TZImageManager manager] createModelWithAsset:asset];
- [[TZImageManager manager] getPhotoWithAsset:assetModel.asset completion:^(UIImage *photo, NSDictionary *info, BOOL isDegraded) {
- if (!isDegraded && photo) {
- [self didFinishWithAddedAsset:assetModel.asset image:photo];
- }
- }];
- }
- }];
- }
- }
- }
- - (void)didFinishWithAddedAsset:(PHAsset *)asset image:(UIImage *)image {
-
- PHAsset *phAsset;
- if ([asset isKindOfClass:[PHAsset class]]) {
- phAsset = asset;
- NSLog(@"location:%@",phAsset.location);
- }
-
- if (self.delegate && [self.delegate respondsToSelector:@selector(didFinishPickingPhotos:sourceAssets:isSelectOriginalPhoto:)]) {
- [self.delegate didFinishPickingPhotos:@[image] sourceAssets:@[phAsset] isSelectOriginalPhoto:NO];
- }
- }
- - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
- if ([picker isKindOfClass:[UIImagePickerController class]]) {
- [picker dismissViewControllerAnimated:YES completion:nil];
- }
- }
- - (UIImagePickerController *)imagePickerVc {
- if (_imagePickerVc == nil) {
- _imagePickerVc = [[UIImagePickerController alloc] init];
- _imagePickerVc.delegate = self;
- UIBarButtonItem *tzBarItem, *BarItem;
- if (@available(iOS 9, *)) {
- tzBarItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[TZImagePickerController class]]];
- BarItem = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UIImagePickerController class]]];
- } else {
- tzBarItem = [UIBarButtonItem appearanceWhenContainedIn:[TZImagePickerController class], nil];
- BarItem = [UIBarButtonItem appearanceWhenContainedIn:[UIImagePickerController class], nil];
- }
- NSDictionary *titleTextAttributes = [tzBarItem titleTextAttributesForState:UIControlStateNormal];
- [BarItem setTitleTextAttributes:titleTextAttributes forState:UIControlStateNormal];
-
- }
- return _imagePickerVc;
- }
- #pragma mark - UIAlertViewDelegate
- - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
- if (buttonIndex == 1) { // 去设置界面,开启相机访问权限
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
- }
- }
- #pragma mark - TZImagePickerController
- - (void)pushTZImagePickerController {
- if (self.maxImagesCount <= 0) {
- return;
- }
-
- TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:self.maxImagesCount columnNumber:4 delegate:self pushPhotoPickerVc:YES];
-
- imagePickerVc.allowTakePicture = YES; // 在内部显示拍照按钮
- imagePickerVc.allowTakeVideo = NO; // 在内部显示拍视频按
- imagePickerVc.allowPickingVideo = NO;
-
- imagePickerVc.showSelectBtn = self.showSelectBtn;
- imagePickerVc.allowCrop = self.allowCrop;
- imagePickerVc.needCircleCrop = self.needCircleCrop;
-
- if (self.allowSquareCrop) {
- imagePickerVc.allowCrop = YES;
- imagePickerVc.cropRect = CGRectMake(0, (SCREEN_HEIGHT - SCREEN_WIDTH)/2, SCREEN_WIDTH, SCREEN_WIDTH);
- }
- if (self.allowHorizontalCrop) {
- imagePickerVc.allowCrop = YES;
- float height = SCREEN_WIDTH*0.5;
- imagePickerVc.cropRect = CGRectMake(0, (SCREEN_HEIGHT - height)/2, SCREEN_WIDTH, height);
- }
- [self.parentController presentViewController:imagePickerVc animated:YES completion:nil];
- }
- #pragma mark - TZImagePickerControllerDelegate
- /// User click cancel button
- /// 用户点击了取消
- - (void)tz_imagePickerControllerDidCancel:(TZImagePickerController *)picker {
- // NSLog(@"cancel");
- }
- // 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的时候,会执行下面的代理方法
- // 你也可以设置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 infos:(NSArray<NSDictionary *> *)infos {
-
- if (self.delegate && [self.delegate respondsToSelector:@selector(didFinishPickingPhotos:sourceAssets:isSelectOriginalPhoto:)]) {
- [self.delegate didFinishPickingPhotos:photos sourceAssets:assets isSelectOriginalPhoto:isSelectOriginalPhoto];
- }
- }
- @end
|