UIKit新手求助:如何在Xcode中通过PHImageRequestID显示图片?
适配AVCam延迟照片处理并显示Live Photo方案
核心说明
PHImageRequestID只是PHImageManager发起请求时的标识,不能直接用它获取图片,你需要先拿到拍摄的Live Photo对应的PHAsset(相册资源对象),再通过PHImageManager请求资源并显示。
步骤1:拍摄后保存Live Photo并获取PHAsset
在AVCam的AVCapturePhotoCaptureDelegate代理方法里,保存Live Photo到相册的同时,获取刚生成的PHAsset(比RequestID更实用):
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) { guard error == nil else { return } // 保存Live Photo到系统相册 PHPhotoLibrary.shared().performChanges({ let creationRequest = PHAssetCreationRequest.forLivePhoto() let resourceOptions = PHAssetResourceCreationOptions() // 添加Live Photo的静态图片资源 if let imageData = photo.fileDataRepresentation() { creationRequest.addResource(with: .photo, data: imageData, options: resourceOptions) } // 添加Live Photo的视频资源 if let videoURL = photo.livePhotoMovieFileURL { creationRequest.addResource(with: .pairedVideo, fileURL: videoURL, options: resourceOptions) } }) { [weak self] success, error in guard success, error == nil else { return } // 抓取最新保存的Live Photo Asset let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] fetchOptions.fetchLimit = 1 let livePhotos = PHAsset.fetchAssets(with: .livePhoto, options: fetchOptions) if let latestAsset = livePhotos.firstObject { self?.latestLivePhotoAsset = latestAsset // 保存到全局变量 self?.showPhotoButton.isHidden = false // 显示查看按钮 } } }
提前在类里定义变量:private var latestLivePhotoAsset: PHAsset?
步骤2:添加拍摄完成后的查看按钮
在界面初始化时添加按钮,默认隐藏,拍摄完成后显示:
// 初始化查看按钮 private func setupShowPhotoButton() { let showButton = UIButton(type: .system) showButton.setTitle("查看刚拍的Live Photo", for: .normal) showButton.addTarget(self, action: #selector(showLatestLivePhotoTapped), for: .touchUpInside) showButton.isHidden = true showButton.translatesAutoresizingMaskIntoConstraints = false view.addSubview(showButton) // 布局按钮(底部居中) NSLayoutConstraint.activate([ showButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), showButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20) ]) self.showPhotoButton = showButton }
类里定义按钮变量:private var showPhotoButton: UIButton?
步骤3:按钮点击后显示Live Photo
用PHLivePhotoView来显示Live Photo(支持动态播放),点击可关闭:
@objc private func showLatestLivePhotoTapped() { guard let asset = latestLivePhotoAsset else { return } let requestOptions = PHLivePhotoRequestOptions() requestOptions.deliveryMode = .highQualityFormat // 请求高质量资源 // 请求Live Photo资源 PHImageManager.default().requestLivePhoto(for: asset, targetSize: view.bounds.size, contentMode: .aspectFit, options: requestOptions) { [weak self] livePhoto, info in guard let self = self, let livePhoto = livePhoto else { return } // 切到主线程更新UI DispatchQueue.main.async { let livePhotoView = PHLivePhotoView(frame: self.view.bounds) livePhotoView.livePhoto = livePhoto livePhotoView.autoresizingMask = [.flexibleWidth, .flexibleHeight] livePhotoView.isUserInteractionEnabled = true // 添加点击关闭手势 let tapToClose = UITapGestureRecognizer(target: self, action: #selector(self.hideLivePhotoView)) livePhotoView.addGestureRecognizer(tapToClose) self.view.addSubview(livePhotoView) } } } @objc private func hideLivePhotoView(sender: UITapGestureRecognizer) { sender.view?.removeFromSuperview() }
关键注意点
- 所有UI操作必须在主线程执行,避免界面卡顿或崩溃
- 显示Live Photo必须用
PHLivePhotoView,普通UIImageView只能显示静态帧 - 若你已经持有
PHImageRequestID,它的作用是取消请求(调用PHImageManager.default().cancelImageRequest(requestID)),而非直接获取图片
内容的提问来源于stack exchange,提问作者kaynmanhngen
相关产品推荐
相关产品推荐

