OC 使用TZImagePickerController實現簡單的多圖選擇檢視
阿新 • • 發佈:2018-12-20
1.使用pod在專案中匯入TZImagePickerController:
pod 'TZImagePickerController'
2.建立檢視ImagePickView:
@protocol ImagePickerViewDelegate <NSObject> @optional - (void)imagePickerView:(UIView *)view didFinishPickPhoto:(NSArray<UIImage *> *)photos; @end @interface ImagesPickView : UIView @property (nonatomic, weak)id<ImagePickerViewDelegate>delegate; - (instancetype)initWithFrame:(CGRect)frame andMaxImages:(NSInteger )count imagesNumPerRow:(NSInteger )num; @end //圖片選擇時cell的展示 @interface TZTestCell : UICollectionViewCell @property (nonatomic, strong) UIImageView *imageView; @property (nonatomic, strong) UIImageView *videoImageView; @property (nonatomic, strong) UIButton *deleteBtn; @property (nonatomic, strong) UILabel *gifLable; @property (nonatomic, assign) NSInteger row; @property (nonatomic, strong) id asset; - (UIView *)snapshotView; @end //獲取檢視所在控制器的擴充套件 @interface UIView (Extend) - (UIViewController *)viewController; @end
#import "ImagesPickView.h" #import <TZImagePickerController/TZImagePickerController.h> #import <Photos/Photos.h> #import <TZImagePickerController/UIView+Layout.h> #import <TZImagePickerController/TZImageManager.h> @interface ImagesPickView ()<UICollectionViewDelegate,UICollectionViewDataSource,TZImagePickerControllerDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate> /**圖片存放父檢視*/ @property (nonatomic, strong)UICollectionView *imageCollectionView; /**最大可選圖片數量*/ @property (nonatomic, assign)NSInteger maxImages; /**每行展示的圖片數量*/ @property (nonatomic, assign)NSInteger imagesCountPerRow; /**已選擇的圖片*/ @property (nonatomic, strong)NSMutableArray *selectedPhotos; /**已選擇的資源*/ @property (nonatomic, strong)NSMutableArray *selectedAssets; @end @implementation ImagesPickView #pragma makr - 初始化方法 -(instancetype)initWithFrame:(CGRect)frame andMaxImages:(NSInteger)count imagesNumPerRow:(NSInteger)num { if ([super initWithFrame:frame]) { self.maxImages = count; self.imagesCountPerRow = num; self.selectedPhotos = [NSMutableArray array]; self.selectedAssets = [NSMutableArray array]; [self addSubview:self.imageCollectionView]; self.frame = CGRectMake(frame.origin.x, frame.origin.y, self.frame.size.width, self.imageCollectionView.frame.size.height); } return self; } #pragma makr - UICollectionViewDelegate UICollectionViewDataSource - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return _selectedPhotos.count + 1; } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { TZTestCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"TZTestCell" forIndexPath:indexPath]; cell.videoImageView.hidden = YES; cell.gifLable.hidden = YES; if (indexPath.row == self.selectedPhotos.count) { //需要展示新增指示圖片 cell.imageView.image = [UIImage imageNamed:@"icon-tj"]; cell.deleteBtn.hidden = YES; }else { //普通的圖片展示 cell.imageView.image = _selectedPhotos[indexPath.row]; cell.asset = self.selectedAssets[indexPath.row]; cell.deleteBtn.hidden = NO; } cell.deleteBtn.tag = indexPath.row; [cell.deleteBtn addTarget:self action:@selector(deleteAction:) forControlEvents:UIControlEventTouchUpInside]; return cell; } - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == self.selectedPhotos.count) { //點選的是新增cell if (self.selectedPhotos.count == self.maxImages) { //已經不能再選擇圖片了 NSString *title = [NSString stringWithFormat:[NSBundle tz_localizedStringForKey:@"Select a maximum of %zd photos"], self.maxImages]; [[[TZImagePickerController alloc]init] showAlertWithTitle:title]; return; }else { //選擇圖片 UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"請選擇圖片來源" message:nil preferredStyle:UIAlertControllerStyleActionSheet]; UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { //判斷許可權 AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; if (status == AVAuthorizationStatusRestricted || status == AVAuthorizationStatusDenied) { UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"無法使用相機" message:@"請在iPhone的""設定-隱私-相機""中允許訪問相機" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }]; UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"設定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; }]; [alertC addAction:action1]; [alertC addAction:action2]; [self.viewController presentViewController:alertC animated:YES completion:nil]; }else { UIImagePickerController *picker = [[UIImagePickerController alloc]init]; picker.delegate = self; picker.sourceType = UIImagePickerControllerSourceTypeCamera; [self.viewController presentViewController:picker animated:YES completion:nil]; } }]; UIAlertAction *action2 = [UIAlertAction actionWithTitle:@"相簿" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { TZImagePickerController *picker = [[TZImagePickerController alloc]initWithMaxImagesCount:self.maxImages delegate:self]; picker.selectedAssets = self.selectedAssets; picker.allowTakePicture = NO; [self.viewController presentViewController:picker animated:YES completion:nil]; }]; UIAlertAction *action3 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; [alertC addAction:action1]; [alertC addAction:action2]; [alertC addAction:action3]; [self.viewController presentViewController:alertC animated:YES completion:nil]; } }else { //預覽圖片 TZImagePickerController *imagePicker = [[TZImagePickerController alloc]initWithSelectedAssets:self.selectedAssets selectedPhotos:self.selectedPhotos index:indexPath.row]; imagePicker.allowPickingImage = NO; [self.viewController presentViewController:imagePicker animated:YES completion:nil]; } } #pragma mark - UIImagePickerControllerDelegate - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info { if ([[info objectForKey:UIImagePickerControllerMediaType] isEqualToString:@"public.image"]) { UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage]; [[TZImageManager manager]savePhotoWithImage:image completion:^(PHAsset *asset, NSError *error) { [self.selectedAssets addObject:asset]; [self.selectedPhotos addObject:image]; [self.imageCollectionView reloadData]; [self layoutNewFrame]; if ([self.delegate respondsToSelector:@selector(imagePickerView:didFinishPickPhoto:)]) { [self.delegate imagePickerView:self didFinishPickPhoto:self.selectedPhotos]; } }]; } [picker dismissViewControllerAnimated:YES completion:nil]; } - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { [picker dismissViewControllerAnimated:YES completion:nil]; } #pragma mark - TZImagePickerControllerDelegate - (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray<UIImage *> *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto infos:(NSArray<NSDictionary *> *)infos { _selectedAssets = [NSMutableArray arrayWithArray:assets]; _selectedPhotos = [NSMutableArray arrayWithArray:photos]; [_imageCollectionView reloadData]; [self layoutNewFrame]; if ([self.delegate respondsToSelector:@selector(imagePickerView:didFinishPickPhoto:)]) { [self.delegate imagePickerView:self didFinishPickPhoto:self.selectedPhotos]; } } #pragma mark - 刪除圖片 - (void)deleteAction:(UIButton *)sender { [_selectedAssets removeObjectAtIndex:sender.tag]; [_selectedPhotos removeObjectAtIndex:sender.tag]; [_imageCollectionView performBatchUpdates:^{ NSIndexPath *indexPath = [NSIndexPath indexPathForRow:sender.tag inSection:0]; [self.imageCollectionView deleteItemsAtIndexPaths:@[indexPath]]; } completion:^(BOOL finished) { [self.imageCollectionView reloadData]; [self layoutNewFrame]; }]; if ([self.delegate respondsToSelector:@selector(imagePickerView:didFinishPickPhoto:)]) { [self.delegate imagePickerView:self didFinishPickPhoto:self.selectedPhotos]; } } #pragma makr - 懶載入 - (UICollectionView *)imageCollectionView { if (!_imageCollectionView) { //圖片的寬度 圖片直接的間隔是5 CGFloat imgItemWidth = (self.frame.size.width - (self.imagesCountPerRow + 1) * 5) / self.imagesCountPerRow; UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init]; layout.itemSize = CGSizeMake(imgItemWidth, imgItemWidth); layout.minimumLineSpacing = 5; layout.minimumInteritemSpacing = 5; _imageCollectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, imgItemWidth + 10) collectionViewLayout:layout]; _imageCollectionView.backgroundColor = [UIColor whiteColor]; _imageCollectionView.contentInset = UIEdgeInsetsMake(5, 5, 5, 5); _imageCollectionView.delegate = self; _imageCollectionView.dataSource = self; _imageCollectionView.scrollEnabled = NO; [_imageCollectionView registerClass:[TZTestCell class] forCellWithReuseIdentifier:@"TZTestCell"]; } return _imageCollectionView; } #pragma mark - 重新設定檢視尺寸 - (void)layoutNewFrame{ NSInteger lineCount = ceil(self.selectedPhotos.count / self.imagesCountPerRow) + 1; CGFloat imgItemWidth = (self.frame.size.width - (self.imagesCountPerRow + 1) * 5) / self.imagesCountPerRow; self.imageCollectionView.frame = CGRectMake(0, 0, self.frame.size.width, lineCount *(10 + imgItemWidth)); self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.imageCollectionView.frame.size.height); } /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. - (void)drawRect:(CGRect)rect { // Drawing code } */ @end //cell的實現 @implementation TZTestCell - (instancetype)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { self.backgroundColor = [UIColor whiteColor]; _imageView = [[UIImageView alloc] init]; _imageView.backgroundColor = [UIColor colorWithWhite:1.000 alpha:0.500]; _imageView.contentMode = UIViewContentModeScaleAspectFill; [self addSubview:_imageView]; self.clipsToBounds = YES; _videoImageView = [[UIImageView alloc] init]; _videoImageView.image = [UIImage imageNamedFromMyBundle:@"MMVideoPreviewPlay"]; _videoImageView.contentMode = UIViewContentModeScaleAspectFill; _videoImageView.hidden = YES; [self addSubview:_videoImageView]; _deleteBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [_deleteBtn setImage:[UIImage imageNamed:@"photo_delete"] forState:UIControlStateNormal]; _deleteBtn.imageEdgeInsets = UIEdgeInsetsMake(-10, 0, 0, -10); _deleteBtn.alpha = 0.6; [self addSubview:_deleteBtn]; _gifLable = [[UILabel alloc] init]; _gifLable.text = @"GIF"; _gifLable.textColor = [UIColor whiteColor]; _gifLable.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.8]; _gifLable.textAlignment = NSTextAlignmentCenter; _gifLable.font = [UIFont systemFontOfSize:10]; [self addSubview:_gifLable]; } return self; } - (void)layoutSubviews { [super layoutSubviews]; _imageView.frame = self.bounds; _gifLable.frame = CGRectMake(self.tz_width - 25, self.tz_height - 14, 25, 14); _deleteBtn.frame = CGRectMake(self.tz_width - 36, 0, 36, 36); CGFloat width = self.tz_width / 3.0; _videoImageView.frame = CGRectMake(width, width, width, width); } - (void)setAsset:(PHAsset *)asset { _asset = asset; _videoImageView.hidden = asset.mediaType != PHAssetMediaTypeVideo; _gifLable.hidden = ![[asset valueForKey:@"filename"] containsString:@"GIF"]; } - (void)setRow:(NSInteger)row { _row = row; _deleteBtn.tag = row; } - (UIView *)snapshotView { UIView *snapshotView = [[UIView alloc]init]; UIView *cellSnapshotView = nil; if ([self respondsToSelector:@selector(snapshotViewAfterScreenUpdates:)]) { cellSnapshotView = [self snapshotViewAfterScreenUpdates:NO]; } else { CGSize size = CGSizeMake(self.bounds.size.width + 20, self.bounds.size.height + 20); UIGraphicsBeginImageContextWithOptions(size, self.opaque, 0); [self.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage * cellSnapshotImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); cellSnapshotView = [[UIImageView alloc]initWithImage:cellSnapshotImage]; } snapshotView.frame = CGRectMake(0, 0, cellSnapshotView.frame.size.width, cellSnapshotView.frame.size.height); cellSnapshotView.frame = CGRectMake(0, 0, cellSnapshotView.frame.size.width, cellSnapshotView.frame.size.height); [snapshotView addSubview:cellSnapshotView]; return snapshotView; } @end //實現獲取檢視所在控制器的擴充套件 @implementation UIView (Extend) - (UIViewController *)viewController { for (UIView* next = [self superview]; next; next = next.superview) { UIResponder* nextResponder = [next nextResponder]; if ([nextResponder isKindOfClass:[UIViewController class]]) { return (UIViewController*)nextResponder; } } return nil; } @end
3.使用方法:
ImagesPickView *imageP = [[ImagesPickView alloc]initWithFrame:CGRectMake(0, 0, UI_SCREEN_WIDTH, 200) andMaxImages:9 imagesNumPerRow:3];
imageP.delegate = self;
[self.view addSubview:imageP];
#pragma mark -ImagePickerViewDelegate - (void)imagePickerView:(UIView *)view didFinishPickPhoto:(NSArray<UIImage *> *)photos { NSLog(@"%@",photos); }