iOS 系统提供的媒体资源选择器(PHPickerViewController)

简介

在前面的博客中我们已经介绍了一个系统为我们提供的媒体选择器UIImagePickerController,它的功能很强大,但是唯一的不足就是只能选取单个媒体资源,而PHPickerViewController恰恰弥补了这一空缺。

PHPickerViewController是iOS 14及更高版本中引入的一个现代化媒体选择器,旨在替代UIImagePickerController。它不仅提供了更灵活的媒体选择功能,还拥有更现代的用户界面。PHPickerViewController允许用户在一次选择操作中选择多个图片和视频,并且可以对选择的媒体类型进行更加细致的控制,例如仅选择图片、视频或Live Photos等。此外,PHPickerViewController不再需要用户授予应用完整的照片库访问权限,只需有限的选择访问权限,从而提高了用户隐私。

在本篇博客中,我们将详细介绍如何使用PHPickerViewController来实现多媒体选择功能,并展示其在实际应用中的优势和使用场景。

基本用法

  • 导入PhotosUI框架
Swift 复制代码
import PhotosUI
  • 初始化和配置PHPickerViewController
Swift 复制代码
var configuration = PHPickerConfiguration()
configuration.selectionLimit = 9 // 可选项,限制选择的媒体数量
configuration.filter = .images // 过滤选项,可以选择.images, .videos, 或 .any
let picker = PHPickerViewController(configuration: configuration)
picker.delegate = self
present(picker, animated: true, completion: nil)
  • 实现代理方法,获取用户选择媒体资源
Swift 复制代码
extension YourViewController: PHPickerViewControllerDelegate {
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true, completion: nil)
        for result in results {
            result.itemProvider.loadObject(ofClass: UIImage.self) { (object, error) in
                if let image = object as? UIImage {
                    DispatchQueue.main.async {
                        // 使用选择的图像
                    }
                }
            }
        }
    }
}

进阶配置

PHPickerViewController本身并没有提供什么配置的接口或者是属性,因为它的配置信息全都交给了configuration属性。

PHPickerConfiguration主要用于定制媒体选择器的行为和外观,下面我逐个来介绍一下:

  • **selectionLimit:**Int类型,设置用户可以选择媒体的最大数量,当设置为0时表示没有任何限制。
Swift 复制代码
configuration.selectionLimit = 5 // 允许选择最多5个媒体
  • **filter:**PHPickerFilter类型,设置允许选择的媒体类型,比如.images,.vides.或者.any。
Swift 复制代码
configuration.filter = .images // 只允许选择图片
configuration.filter = .any // 允许选择图片和视频
  • preferredAssetRepresentationMode: PHPickerConfiguration.AssetRepresentationMode,可以选择.automatic,.current或者.compatible,它决定了在选择媒体时应该使用的资源表示形式,在处理媒体文件的质量和兼容性方面非常有用。通常我们会选择.automatic,它通常是指设备的原始表示形式。
Swift 复制代码
configuration.preferredAssetRepresentationMode = .automatic
  • preselectedAssetIdentifiers: [String]类型,它主要用于初始化时显示你已经选择的媒体资源。
Swift 复制代码
 // 设置之前选中的标识符
        if #available(iOS 15.0, *) {
            configuration.preselectedAssetIdentifiers = previouslySelectedIdentifiers
        }
  • photoLibrary: PHPhotoLibrary,用于获取执行相册的媒体资源,默认情况下使用PHPhotoLibrary.shared()
Swift 复制代码
configuration.photoLibrary = PHPhotoLibrary.shared()
  • selection: Selection,用来指定用户选择媒体资源时的行为,有如下选项:.default,.ordered或者.unordered。
Swift 复制代码
configuration.selection = .ordered // 选中的媒体按顺序排列

使用示例

对于上面的场景,如果需要一次性选择多张照片(最多可选9张),使用PHPickerViewController是非常合适的选择。

首先我们来设置一些基本属性,比如可选资源最大个数,已选资源列表等等:

Swift 复制代码
    /// 最大数量
    private let maxCount = 9
    /// 已选结果
    private var selectedResults = [PHAlbumModel]()

其中PHAblbuModel是我们自定义数据模型,我们只需要图片资源和资源标识这两个数据,代码如下:

Swift 复制代码
class PHAlbumModel: NSObject {
    /// 图片
    var image:UIImage?
    /// 标识
    var identifier:String?
}

接下来我们来实现列表中的第一个元素的事件,显示多媒体资源选择视图控制器,代码如下:

Swift 复制代码
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if indexPath.row == 0 {
            // 选择图片
            showAlbum()
        }
    }
Swift 复制代码
    @objc func showAlbum() {
        if self.selectedResults.count >= maxCount {
            print("已经达到最大选择数量")
            return
        }
        var configuration = PHPickerConfiguration()
        // 资源类型
        configuration.filter = .images
        // 最大数量
        configuration.selectionLimit = maxCount - self.selectedResults.count + 1
        configuration.selection = .ordered
        // 预选资源
        var preselectedAssetIdentifiers = [String]()
        for model in selectedResults {
            if let identifier = model.identifier , identifier != "" {
                preselectedAssetIdentifiers.append(identifier)
            }
        }
        configuration.preselectedAssetIdentifiers = preselectedAssetIdentifiers
        let mediaPikcerViewController = PHPickerViewController(configuration: configuration)
        mediaPikcerViewController.delegate = self
        present(mediaPikcerViewController, animated: true, completion: nil)
        
    }

在上面的代码中:

我们过滤了资源的类型,只需要图片类型的媒体资源。

设置了资源的最大数量为,为最大数量减去已经选择的媒体数量。

设置了选中资源的显示顺序。

并且也设置了我们当前已经选择的媒体资源。

接下来来看一下代理方法的实现:

Swift 复制代码
    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        picker.dismiss(animated: true, completion: nil)
        for result in results {
            let itemProvider = result.itemProvider
            if itemProvider.canLoadObject(ofClass: UIImage.self) {
                itemProvider.loadObject(ofClass: UIImage.self) { [weak self] image, error in
                    if let image = image as? UIImage {
                        let model = PHAlbumModel()
                        print("获取到图片 \(result.assetIdentifier)")
                        model.image = image
                        model.identifier = result.assetIdentifier
                        self?.selectedResults.append(model)
                        DispatchQueue.main.async {
                            self?.collectionView.reloadData()
                        }
                    }
                }
            }
        }
    }

获取到媒体资源之后,根据所需数据构建了我们自己的数据模型,并且添加到了已选择资源的列表中,回到主线程进行刷线列表。

结语

在本文中,我们详细探讨了 PHPickerViewController,一个用于选择照片和视频的强大工具。通过比较它与 UIImagePickerController 的不同,我们看到了 PHPickerViewController 的优势,特别是在支持多选和灵活配置方面。

PHPickerViewController 不仅简化了用户选择媒体的过程,还提供了更好的用户体验。尽管它不支持拍照或录像功能,但其多选能力和对不同媒体类型的支持,使其在许多应用场景中成为理想选择。通过合适的配置和管理选项,你可以充分利用这个工具,提升应用的功能和用户体验。

希望这篇文章能帮助你更好地理解和应用 PHPickerViewController。如有任何疑问或需要进一步讨论,请随时与我联系。感谢你的阅读和支持!

相关推荐
九州ip动态13 小时前
模拟器多开限制ip,如何设置单窗口单ip,每个窗口ip不同
tcp/ip·游戏·媒体
大霸王龙2 天前
数字媒体需求复用工具(DMReqTool)
python·django·媒体
不能只会打代码2 天前
支持用户注册和登录、发布动态、点赞、评论、私信等功能的社交媒体平台创建!!!
前端·css·后端·html·json·媒体·社交媒体平台
天马37982 天前
C#获取视频第一帧_腾讯云媒体处理获取视频第一帧
云计算·腾讯云·媒体
小不点区块3 天前
海外媒体软文发稿:打开全球传播的新窗口-大舍传媒
传媒·媒体
大舍传媒4 天前
海外媒体发稿:阿拉伯海湾新闻-外媒宣发的魅力与机遇
大数据·人工智能·科技·搜索引擎·媒体
我叫汪枫4 天前
SSM post接口传递json 报错 HTTP状态 415 - 不支持的媒体类型
http·json·媒体
小不点区块4 天前
海外媒体发稿:中东地区阿拉伯邮报Arab Post新闻媒体宣发
大数据·人工智能·搜索引擎·媒体
51媒体网-媒体邀约4 天前
「51媒体」:企业成长助推器
媒体
EasyGBS4 天前
国标GB28181摄像机接入EasyGBS国标GB28181设备管理软件:GB28181-2022媒体传输协议解析
安全·音视频·媒体·视频监控·gb28181