PhotoKit框架,多选图片和图片游览Demo

xcode 8的到来意味着ios8以下的要慢慢的被抛弃了,所有我在这里写了一个多选图片的Demo.(多选图片的Demo网上有很多了,我只是把自己学到的东西跟大家交流交流,请不要太认真哦)
在这里我就不说AssetsLibrary了

  • PhotoKit属性介绍
 PHAsset 代表照片库中的一个资源,通过PHAsset可以获取和保存资源。(白话就是:你想要图片就要用他去取)
 PHFetchOptions 获取资源时的参数,可以传Nil,系统会有默认值。
 PHAssetCollection: PHCollecion的子类,表示一个时刻或者一个相册。
 PHFetchResult:表示一系列的资源结果集合,也可以是相册的集合。
 PHImageManager: 用于处理资源的加载,加载图片的过程带有缓存处理,可以通过传入一个 PHImageRequestOptions 控制资源的输出尺寸等 规格
 PHImageRequestOptions: 如上面所说,控制加载图片时的一系列参数

获取用户相册

PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];//这里可以不用创建
    //PHAssetCollectionTypeSmartAlbum 表示智能相册 PHAssetCollectionSubtypeAlbumRegular 用户创建所有的相册
    PHFetchResult *smartAlbumsFetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:fetchOptions];

    //注意类型
    for (PHAssetCollection *sub in smartAlbumsFetchResult){
        //遍历到数组中
        PHFetchResult *group = [PHAsset fetchAssetsInAssetCollection:sub options:nil];
        //过滤掉没有图片的Group
        if (group.count > 0) {
            [self.groupList addObject:sub];
        }
    }

PHAssetCollectionTypeSmartAlbum 表示智能相册
PHAssetCollectionTypeAlbum表示专辑
PHAssetCollectionTypeMoment表示时刻

PHAssetCollectionSubtypeAlbumRegular 用户在 Photos 中创建的相册
PHAssetCollectionSubtypeSmartAlbumPanoramas 相机拍摄的全景照片
PHAssetCollectionSubtypeSmartAlbumBursts 连拍模式拍摄的照片
PHAssetCollectionSubtypeSmartAlbumUserLibrary 所有的照片都会在这里面

显示用户的相册(获取最后一张图片)
@property (nonatomic, strong) PHFetchResult *group;

[[PHImageManager defaultManager] requestImageForAsset:group.lastObject targetSize:CGSizeMake(screen_width,screen_height) contentMode:PHImageContentModeAspectFit options:nil resultHandler:^(UIImage *result, NSDictionary *info) {
        _imageView.image = result;
    }];

显示相册名和图片的数量

PHAssetCollection *_titleAsset;
- (void)setGroupList:(NSMutableArray *)groupList{
    _groupList = groupList;
    _titleAsset = [_groupList objectAtIndex:_row];
    //显示相薄名称+图片张数
    _textLabel.text = [NSString stringWithFormat:@"%@(%zi张)",[NSString stringWithFormat:@"%@",_titleAsset.localizedTitle], _group.count];
    [_textLabel sizeToFit];
}

获取到某个相册的所有图片(我是用collectionView来展示的)

  1. 设置数据源
NSMutableArray *photoList = [[NSMutableArray alloc] init];
    //把数据封装成一个模型 方便以后使用
    for (PHAsset *asset in _group) {
        if (asset.mediaType == PHAssetMediaTypeImage) {
            PhotoModel *model = [[PhotoModel alloc] init];
            model.asset = asset;

            //获取缩略图大小
            CGFloat scale = screen_width / screen_height;
            CGSize resize = CGSizeMake(asset.pixelWidth * scale, asset.pixelHeight * scale);
            model.thumbSize = CGSizeMake(_collectionView.frame.size.height / resize.height * resize.width, _collectionView.frame.size.height);
            [photoList addObject:model];
        }
    }
    _assetList = [NSMutableArray arrayWithArray:[photoList reverseObjectEnumerator].allObjects];
  1. 展示数据
    注意几个方面
    1.也就是用模型的好处,我拿到了高清的图片就把它添加到模型里 面,下次就不需要在去加载了。
    2.在说一下resizeMode的作用,esizeMode 属性控制图像的剪裁,
    PHImageRequestOptionsResizeModeExact 则返回图像必须和目标大小相匹配,并且图像质量也为高质量图像
    PHImageRequestOptionsResizeModeFast 则请求的效率更高,但返回的图像可能和目标大小不一样并且质量较低。
    PHImageRequestOptionsResizeModeNone 没有大小
    我这里选择PHImageRequestOptionsResizeModeFast是因为我只需要加载的效率。
    还有其他的属性我就不一一的说了。
- (void)setModel:(PhotoModel *)model {
    _model = model;
    _imageView.frame = self.bounds;
    if (_model.image) {
        _imageView.image = _model.image;
    }else{
        PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
        options.resizeMode = PHImageRequestOptionsResizeModeExact;
        options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
        [[PHImageManager defaultManager] requestImageForAsset:_model.asset targetSize:CGSizeMake(screen_width, screen_height) contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
            NSLog(@"%@",result);
//            //判断是否是高清的图片
            BOOL downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
                if (_model == model) {
                    if (downloadFinined) {
                        _model.image = result;
                    }
                    _model.thumbImage = result;
                    _imageView.image = result;
                }
        }];
    }
}

图片游览 之前我用的是ScrolleView写,以后发现用collectionView写更好一些,代码也少很多。
重要的代码都在collectionViewCell里面

- (instancetype)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(5, 0, frame.size.width - 10, frame.size.height)];
        _scrollView.delegate = self;
        _scrollView.backgroundColor = [UIColor redColor];
        _scrollView.minimumZoomScale = 1;
        _scrollView.maximumZoomScale = 2.8;
        _scrollView.showsHorizontalScrollIndicator = NO;
        [self.contentView addSubview:_scrollView];

        UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapEvent)];
        [_scrollView addGestureRecognizer:singleTap];

        UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTapEvent:)];
        doubleTap.numberOfTapsRequired = 2;
        [_scrollView addGestureRecognizer:doubleTap];

        [singleTap requireGestureRecognizerToFail:doubleTap];

        _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, _scrollView.frame.size.width, _scrollView.frame.size.height)];
        [_scrollView addSubview:_imageView];

    }
    return self;
}

- (void)setModel:(PhotoModel *)model{
    _model = model;
    if (_model.image) {
        _imageView.image = _model.image;
    }else{
        [[PHImageManager defaultManager] requestImageForAsset:_model.asset targetSize:CGSizeMake(screen_width, screen_height) contentMode:PHImageContentModeAspectFit options:nil resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
            BOOL downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
                if (_model == model) {
                    if (downloadFinined) {
                        _model.image = result;
                        _imageView.image = _model.image;
                    }else{
                        _model.thumbImage = result;
                        _imageView.image = result;
                    }
                }
        }];
    }
    [self setImageFrame];
}

- (void)setImageFrame{
    UIImage *image = _imageView.image;
    CGFloat scale = 0;
    if (image && image.size.width > 0) {
        scale = [UIScreen mainScreen].bounds.size.width / image.size.width;
    }

    CGRect frame = _imageView.frame;
    frame.size.width = [UIScreen mainScreen].bounds.size.width;
    frame.size.height = scale * image.size.height;
    frame.origin.x = 0;
    if (frame.size.height > self.frame.size.height) {
        frame.origin.y = 0;
    }else{
        frame.origin.y = (self.frame.size.height - frame.size.height) / 2;
    }
    _imageView.frame = frame;
}

- (void)zoomToMinimumScale{
    [_scrollView setZoomScale:_scrollView.minimumZoomScale animated:YES];
}

#pragma mark - ---------------------- UIScrollViewDelegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return _imageView;
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
    if (scrollView.zoomScale > scrollView.maximumZoomScale){
        [scrollView setZoomScale:scrollView.maximumZoomScale animated:YES];
    }
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    //放大过程中需要设置图片的中心点
    CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width) ? (scrollView.bounds.size.width - scrollView.contentSize.width)/2 : 0.0;
    CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height)?(scrollView.bounds.size.height - scrollView.contentSize.height)/2 : 0.0;
    _imageView.center = CGPointMake(scrollView.contentSize.width/2 + offsetX,scrollView.contentSize.height/2 + offsetY);
}

#pragma mark - ---------------------- 事件
- (void)singleTapEvent{
    if (self.collectionViewCellDelgate && [self.collectionViewCellDelgate respondsToSelector:@selector(hidenPhotoBrowse)]) {
        [self.collectionViewCellDelgate hidenPhotoBrowse];
    }
}

- (void)doubleTapEvent:(UITapGestureRecognizer *)sender{
    if (_scrollView.zoomScale != _scrollView.minimumZoomScale) {
        [_scrollView setZoomScale:_scrollView.minimumZoomScale animated:YES];
    }else{
        //放大倍数
        CGFloat scale = _scrollView.maximumZoomScale;
        CGFloat newWidth = _scrollView.bounds.size.width / scale;
        CGFloat newHeight = _scrollView.bounds.size.height / scale;

        //获取双击的点
        CGFloat touchX = [sender locationInView:sender.view].x;
        CGFloat touchY = [sender locationInView:sender.view].y;

        CGRect frame = CGRectMake(touchX - newWidth/2, touchY - newHeight/2, newWidth, newHeight);
        [_scrollView zoomToRect:frame animated:YES];
    }
}

基本上重点的我都说了,下面说一下我在做的时候出现的问题吧。之前我用过异步去加载数据源为了解决卡顿的问题,卡顿会在1000张以上的时候出现。用异步就出问题,Photokit本身就有同步和异步,synchronous这个属性就是是否同步。多选图片这要的问题就图片加载的时候,出现的卡顿。图片的质量。好吧,或许不是很详细。大家可以下载我的Demo看看。有什么问题可以留言给我。
https://github.com/OneGangk/SelectImageDemo 这个是我用xcode 8写的可能有些人没有更新
https://github.com/OneGangk/PhotoSelectedMore xcode 7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值