iOS Swift中如何从图库获取Live Photo并在Collection View中展示?
在iOS Swift中获取Live Photo并在Collection View中展示
我来帮你梳理一下完整的实现流程,分为获取Live Photo资源和Collection View网格展示两个核心部分:
1. 获取图库中的Live Photo资源
你提供的fetchLivePhotos()函数已经搞定了核心的资源筛选与获取,我来拆解下关键逻辑:
- 先通过
PHFetchOptions设置排序规则(按创建日期倒序,最新的Live Photo优先显示) - 用谓词精准筛选出带有
photoLive子类型的资产,确保只获取Live Photo - 因为资源获取是耗时操作,放到全局队列异步执行,避免阻塞主线程,获取完成后切回主线程刷新Collection View
完整代码如下:
func fetchLivePhotos() { let options = PHFetchOptions() options.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] options.predicate = NSPredicate(format: "(mediaSubtype & %d) != 0", PHAssetMediaSubtype.photoLive.rawValue) DispatchQueue.global(qos: .default).async { self.livePhotoAssets = PHAsset.fetchAssets(with: options) DispatchQueue.main.async { self.collectionView?.reloadData() } } }
2. Collection View网格展示实现
第一步:设置Collection View布局
在viewDidLoad里配置流式布局,实现3列网格效果(你可以根据需求调整列数和间距):
override func viewDidLoad() { super.viewDidLoad() // 配置流式布局 let layout = UICollectionViewFlowLayout() let spacing: CGFloat = 8 let itemWidth = (UIScreen.main.bounds.width - spacing * 4) / 3 // 3列 + 左右边距 layout.itemSize = CGSize(width: itemWidth, height: itemWidth) layout.minimumInteritemSpacing = spacing layout.minimumLineSpacing = spacing layout.sectionInset = UIEdgeInsets(top: spacing, left: spacing, bottom: spacing, right: spacing) collectionView.collectionViewLayout = layout collectionView.register(LivePhotoCell.self, forCellWithReuseIdentifier: "LivePhotoCell") // 开始获取Live Photo fetchLivePhotos() }
第二步:自定义Live Photo展示Cell
创建一个包含PHLivePhotoView的自定义Cell,专门用来展示Live Photo:
class LivePhotoCell: UICollectionViewCell { let livePhotoView = PHLivePhotoView() override init(frame: CGRect) { super.init(frame: frame) setupSubviews() } required init?(coder: NSCoder) { super.init(coder: coder) setupSubviews() } private func setupSubviews() { livePhotoView.frame = bounds livePhotoView.contentMode = .scaleAspectFill livePhotoView.clipsToBounds = true livePhotoView.startPlayback(with: .hint) // 可选:自动播放提示动画 contentView.addSubview(livePhotoView) } }
第三步:实现Collection View数据源方法
把获取到的Live Photo资源绑定到Cell上,这里用PHImageManager来请求高清的Live Photo资源:
extension YourViewController: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return livePhotoAssets?.count ?? 0 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "LivePhotoCell", for: indexPath) as! LivePhotoCell guard let livePhotoAsset = livePhotoAssets?.object(at: indexPath.item) else { return cell } // 配置Live Photo请求选项 let requestOptions = PHLivePhotoRequestOptions() requestOptions.deliveryMode = .highQualityFormat requestOptions.isNetworkAccessAllowed = true // 允许从iCloud加载资源 requestOptions.progressHandler = { progress, _, _, _ in // 可选:处理加载进度,显示进度条 DispatchQueue.main.async { // 更新UI } } // 请求并加载Live Photo到Cell PHImageManager.default().requestLivePhoto( for: livePhotoAsset, targetSize: cell.livePhotoView.bounds.size, contentMode: .aspectFill, options: requestOptions ) { livePhoto, info in DispatchQueue.main.async { cell.livePhotoView.livePhoto = livePhoto } } return cell } }
注意事项
- 别忘了在
Info.plist中添加NSPhotoLibraryUsageDescription键,填写访问图库的权限说明,否则App会崩溃 - 如果需要支持iCloud照片,确保开启
isNetworkAccessAllowed,并处理加载中的占位状态 PHLivePhotoView默认支持长按播放Live Photo,你也可以通过startPlayback(with:)和stopPlayback()方法手动控制播放逻辑
内容的提问来源于stack exchange,提问作者Pratik Panchal
相关产品推荐
相关产品推荐

