iOS14 新特性 照片挑选器 PhotosUI

4,718 阅读2分钟

Created by Joker 2020/08/05

效果预览

单选效果

  • 与使用UIImagePickerController效果一致

多选效果

  • 选择多个,未达到上限时

  • 选择多个,达到可选上限

  • 查看选中图片

iOS 14 以前

UIImagePickerController 使用

  • 导入头文件
#import <UIKit/UIImagePickerController.h>
  • 遵循代理协议

因为 UIImagePickerController 继承于 UINavigationController,所以需要遵循 UINavigationControllerDelegate

@property(nullable,nonatomic,weak)      id <UINavigationControllerDelegate, UIImagePickerControllerDelegate> delegate;
  • 图片来源
@property(nonatomic)           UIImagePickerControllerSourceType     sourceType;                                                        // default value is UIImagePickerControllerSourceTypePhotoLibrary.
  • 多媒体类型
@property(nonatomic,copy)      NSArray<NSString *>                   *mediaTypes;
    // default value is an array containing kUTTypeImage.
  • 选择照片后是否允许编辑
@property(nonatomic)           BOOL                                  allowsEditing API_AVAILABLE(ios(3.1));     // replacement for -allowsImageEditing; default value is NO.
  • 代码示例
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;  // 设置代理
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;  // 照片库
picker.allowsEditing = YES; // 支持编辑图片

[self presentViewController:picker animated:YES completion:nil];  // 展示照片选择页面
  • UIImagePickerControllerDelegate 代理协议
// 用户完成图片选择后回调
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<UIImagePickerControllerInfoKey,id> *)info {
    // dismiss
    [picker dismissViewControllerAnimated:YES completion:nil];
    
    // 提取图片信息
    UIImage *image = [info objectForKey:UIImagePickerControllerOriginalImage];
    __weak typeof(self) weakSelf = self;
    dispatch_async(dispatch_get_main_queue(), ^{
        __strong typeof(weakSelf) strongSelf = weakSelf;
        strongSelf.imageView.image = image;
    });
    
}
// 取消选择回调
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    // dismiss
    [picker dismissViewControllerAnimated:YES completion:nil];
}

iOS 14 开始

PHPickerViewController 使用

  • 导入头文件
#import <PhotosUI/PhotosUI.h>
  • 初始化配置
/// The configuration passed in during initialization.
@property (NS_NONATOMIC_IOSONLY, copy, readonly) PHPickerConfiguration *configuration NS_REFINED_FOR_SWIFT;
  • PHPickerConfiguration 可选配置项
/// 最大选择上限
/// Maximum number of assets that can be selected. Default is 1.
/// @discussion Setting \c selectionLimit to 0 means maximum supported by the system.
@property (NS_NONATOMIC_IOSONLY) NSInteger selectionLimit;
/// 多媒体类型
/// Applying a filter to restrict the types that can be displayed. Default is \c nil.
/// @discussion Setting \c filter to \c nil means all asset types can be displayed.
@property (NS_NONATOMIC_IOSONLY, copy, nullable) PHPickerFilter *filter;
  • 遵循代理协议
/// The delegate to be notified.
@property (NS_NONATOMIC_IOSONLY, weak) id<PHPickerViewControllerDelegate> delegate NS_REFINED_FOR_SWIFT;
  • 代码示例
// 初始化配置项
PHPickerConfiguration *configuration = [PHPickerConfiguration new];
configuration.selectionLimit = 0;  // 设置最大选择上线,默认为1(即单选),0表示跟随系统允许的上限

PHPickerFilter *imagesFilter = [PHPickerFilter imagesFilter];
PHPickerFilter *videosFilter = [PHPickerFilter videosFilter];
PHPickerFilter *livePhotosFilter = [PHPickerFilter livePhotosFilter];
configuration.filter = [PHPickerFilter anyFilterMatchingSubfilters:@[imagesFilter]];  // 设置多媒体类型,默认为 imagesFilter

// 使用配置初始化照片选择控制器
PHPickerViewController *pickerCro = [[PHPickerViewController alloc] initWithConfiguration:configuration];
pickerCro.delegate = self;  // 设置代理

[self presentViewController:pickerCro animated:YES completion:nil];
  • 实现 PHPickerViewControllerDelegate 代理协议(必须)
- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results API_AVAILABLE(ios(14)) {
    [picker dismissViewControllerAnimated:YES completion:nil];
    
    PHPickerResult *pickerResult = [self.mutResults objectAtIndex:index];
    NSItemProvider *itemProvider = pickerResult.itemProvider;
    if ([itemProvider canLoadObjectOfClass:[UIImage class]]) {
        __weak typeof(self) weakSelf = self;
        [itemProvider loadObjectOfClass:[UIImage class] completionHandler:^(__kindof id<NSItemProviderReading>  _Nullable object, NSError * _Nullable error) {
            if ([object isKindOfClass:[UIImage class]]) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    __strong typeof(weakSelf) strongSelf = weakSelf;
                    strongSelf.imageView.image = object;
                });
            } else {
                NSLog(@"Error: %@", error);
            }
        }];
    } else {
        NSLog(@"Error cannot load.");
    }
}

对比

对比项UIImagePickerControllerPHPickerViewController
系统支持2.0 ~ 13.x14.0 ~
frameworkUIKitPhotosUI
是否多选
是否可以编辑
读取图片是否需要隐私授权
支持的媒体类型图片、实况、视频图片、实况、视频
选中后返回数据(NSDictionary<UIImagePickerControllerInfoKey,id> *)info(NSArray<PHPickerResult *> *)results