ios 自制相册 显示所有图片和视频 有提到解决UICollectionVIew布局混乱

1.Privacy - Photo Library Usage Description 权限写入info.plist

2.自定义UICollectionViewController

#import <UIKit/UIKit.h>
#import <Photos/Photos.h>
#import "XMPickImageCollectionViewCell.h"
#import "XMPublishContentVideoController.h"
NS_ASSUME_NONNULL_BEGIN

@interface XMPickImageViewController : UICollectionViewController
//获取所有视频和图片集合
@property (nonatomic,strong) NSMutableArray *photoArray;

//如果是视频时显示的图片字典
@property (nonatomic,strong) NSMutableDictionary *imageDic;

//如果是视频时存的AVPlaver字典
@property (nonatomic,strong) NSMutableDictionary *vedioDic;


@end

NS_ASSUME_NONNULL_END




#import "XMPickImageViewController.h"
//继承代理
@interface XMPickImageViewController ()<UICollectionViewDelegate>

@end

@implementation XMPickImageViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //初始化存放所有视频和图片的集合
    self.photoArray = [[NSMutableArray alloc] init];
    //获取所有类型为图片的资源
    PHFetchResult<PHAsset *> *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:nil];
    self.imageDic = [[NSMutableDictionary alloc] init];
    PHImageManager *imageManger = [PHImageManager defaultManager];
    
    for (PHAsset *asset in fetchResult) {
        
        //通过PHImageManager从资源中取图片
        [imageManger requestImageForAsset:asset targetSize:CGSizeMake(110, 110) contentMode:PHImageContentModeDefault options:nil resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
        	//放入集合
            [self.photoArray addObject:result];
            
        }];
        
    }
    //获取所有类型为媒体的资源
    fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeVideo options:nil];
    
    for (PHAsset *asset in fetchResult) {
		//通过PHImageManager从资源中取视频
        [imageManger requestAVAssetForVideo:asset options:nil resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
            if ([asset isKindOfClass:[AVURLAsset class]]) {
				//放入集合
                [self.photoArray addObject:asset];
         }}];
    }
    //重新加载相册
    [self.collectionView reloadData];
    
}

/**
手指拖动滑行
@param decelerate 滑动明确位移返回NO,自动滑行一段位移返回YES
*/

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    return 1;
}

// 设置cell大小 itemSize:可以给每一个cell指定不同的尺寸
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    return CGSizeMake(110, 110);
}

#pragma mark - UICollectionViewDataSource
// 每个分区上得元素个数
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.photoArray.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
//使用可复用的单元格
    XMPickImageCollectionViewCell *cell =(XMPickImageCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"XMPickImageCollectionViewCell" forIndexPath:indexPath];
    //[cell setBackgroundColor:[UIColor redColor]];
    //避免布局混乱,先把cell.contentView的子View删掉    
    for(UIView *view in [cell.contentView subviews])
    {
        [view removeFromSuperview];
    }
    //判断从photoArray中取出来的是视频还是图片
    if ([self.photoArray[indexPath.row] isKindOfClass:[UIImage class]]) {
    //初始化一个UIImageView 通过photoArray取image,因为之前保存进去的就是UIImage类型
        UIImageView *image = [[UIImageView alloc]initWithImage:self.photoArray[indexPath.row]];
        //image.layer.cornerRadius = 22.0f;
        image.clipsToBounds = true;
        //重点,cell.contentView添加 因为前面是删的cell.contentView的子view
        [cell.contentView addSubview:image];
    }
    //判断从photoArray中取出来的是AVURLAsset还是图片
    if ([self.photoArray[indexPath.row] isKindOfClass:[AVURLAsset class]]) {
        AVURLAsset* urlAsset = (AVURLAsset*)self.photoArray[indexPath.row];
		//获取视频url 这里也当字典key使用
        NSString *key = [urlAsset.URL absoluteString];
   
		//通过key从字典取
        AVPlayer *dVedio = [self.vedioDic objectForKey:key];
        //取不到就自己创建
        if (dVedio == nil) {
        	//通过URL创建AVPlayer
            dVedio = [AVPlayer playerWithURL:urlAsset.URL];
        }
        //保存进字典url为key
        [self.vedioDic setObject:dVedio forKey:key];

   		//通过key从字典取
        UIImage *dImage = [self.imageDic objectForKey:key];
        //取不到就自己创建
        if (dImage == nil) {
        	//通过URL获取视频内的截图,当封面
            dImage = [XMPickImageViewController thumbnailImageForVideo:urlAsset.URL atTime:0.1];
        }
        //保存进字典url为key
        [self.imageDic setObject:dImage forKey:key];
        //创建UIImageView
        UIImageView *image = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 110, 110)];
        //UIImageView设置image为刚刚在视频截的封面图
        [image setImage:dImage];
        //可选,因为是相册就预防让他越界
        image.clipsToBounds = true;
        //添加进 cell.contentView
        [cell.contentView addSubview:image];
        //创建显示视频长度的label
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 80, 80, 13)];
        
        NSLog(@"%@",urlAsset.URL);
        
        CMTime time = [urlAsset duration];
        //获取所有秒
        long totalSeconds = ceil(time.value/10/60);
        //除60秒向下取整获得分
        long branch = (floor)(totalSeconds/60.0);
        //取余60取秒
        long seconds = totalSeconds%60;
        
        [label setText:[NSString stringWithFormat:@"%ld:%ld",branch,seconds]];
		//向右对齐
        [label setTextAlignment:NSTextAlignmentRight];
        //白色字体
        [label setTextColor:[UIColor whiteColor]];
        
        //添加进 cell.contentView
        [cell.contentView addSubview:label];
        
    }

    return cell;
}

// 取指定帧数的图片的方法
+ (UIImage*) thumbnailImageForVideo:(NSURL *)videoURL atTime:(NSTimeInterval)time {
    
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
    NSParameterAssert(asset);
    AVAssetImageGenerator *assetImageGenerator =[[AVAssetImageGenerator alloc] initWithAsset:asset];
    assetImageGenerator.appliesPreferredTrackTransform = YES;
    assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
    
    CGImageRef thumbnailImageRef = NULL;
    CFTimeInterval thumbnailImageTime = time;
    NSError *thumbnailImageGenerationError = nil;
    thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60)actualTime:NULL error:&thumbnailImageGenerationError];
    
    if(!thumbnailImageRef)
    NSLog(@"thumbnailImageGenerationError %@",thumbnailImageGenerationError);
    
    UIImage*thumbnailImage = thumbnailImageRef ? [[UIImage alloc]initWithCGImage: thumbnailImageRef] : nil;
    
    return thumbnailImage;
}


- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
	//点击图片回调方法
	if ([self.photoArray[indexPath.row] isKindOfClass:[UIImage class]]) {
	
	        UIImage *image = self.photoArray[indexPath.row];
	        
	    }
	    if ([self.photoArray[indexPath.row] isKindOfClass:[AVURLAsset class]]) {
	        AVURLAsset* urlAsset = (AVURLAsset*)self.photoArray[indexPath.row];

	    }
    
}
/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

行类

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface XMPickImageCollectionViewCell : UICollectionViewCell


@end

NS_ASSUME_NONNULL_END

#import "XMPickImageCollectionViewCell.h"

@implementation XMPickImageCollectionViewCell

@end



发布了11 篇原创文章 · 获赞 5 · 访问量 2145

猜你喜欢

转载自blog.csdn.net/qq_41586150/article/details/104003213