1. 程式人生 > >OC 使用TZImagePickerController實現簡單的多圖選擇檢視

OC 使用TZImagePickerController實現簡單的多圖選擇檢視

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);
}