Swift中照片库资源mediaType不准确及多图选择器开发问题
解决Swift多图选择器中PHAsset mediaType不准确的问题
嘿,我来帮你搞定这个mediaType判断不准的问题!你在开发多图选择器的思路很清晰,现在遇到的类型判断误差,主要是因为依赖字符串存储/判断资源类型或者没有利用PHAsset原生的枚举属性做精准判断,下面给你具体的解决方案:
一、修正资源类型的存储与判断逻辑
首先,不要用String类型来存assetType,改用PHAssetMediaType相关的枚举,这样能从根源上避免字符串匹配的错误。
1. 重构你的PhotoLibraryAsset类
把原来的String类型assetType换成自定义枚举,或者直接使用PHAssetMediaType:
// 自定义枚举更贴合你的业务需求 private enum AssetType { case photo case video } private class PhotoLibraryAsset { var assetType: AssetType var thumbnail: UIImage // 额外存储原始PHAsset,方便后续扩展操作 var originalAsset: PHAsset? init(assetType: AssetType, thumbnail: UIImage, originalAsset: PHAsset?) { self.assetType = assetType self.thumbnail = thumbnail self.originalAsset = originalAsset } }
2. 精准判断PHAsset的类型
获取照片库资源时,直接利用PHAsset的mediaType枚举来判断,不要自己拼接字符串:
// 假设你已经获取到照片库资源的PHFetchResult let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] let fetchResult = PHAsset.fetchAssets(with: .any, options: fetchOptions) fetchResult.enumerateObjects { asset, _, _ in let thumbnailSize = CGSize(width: 80, height: 80) let imageRequestOptions = PHImageRequestOptions() imageRequestOptions.isNetworkAccessAllowed = true // 允许从iCloud获取资源 imageRequestOptions.deliveryMode = .fastFormat // 优先加载低清缩略图提升流畅度 // 根据原生枚举判断资源类型 switch asset.mediaType { case .image: // 处理图片资源(包括Live Photo) PHImageManager.default().requestImage(for: asset, targetSize: thumbnailSize, contentMode: .aspectFill, options: imageRequestOptions) { [weak self] image, _ in guard let image = image else { return } let photoAsset = PhotoLibraryAsset(assetType: .photo, thumbnail: image, originalAsset: asset) self?.assetArray.append(photoAsset) self?.collectionView.reloadData() } case .video: // 处理视频资源,获取视频封面图 PHImageManager.default().requestImage(for: asset, targetSize: thumbnailSize, contentMode: .aspectFill, options: imageRequestOptions) { [weak self] image, _ in guard let image = image else { return } let videoAsset = PhotoLibraryAsset(assetType: .video, thumbnail: image, originalAsset: asset) self?.assetArray.append(videoAsset) self?.collectionView.reloadData() } case .audio: // 音频资源,根据你的需求决定是否处理 break default: break } }
二、处理特殊资源的二次验证
有些特殊资源(比如Live Photo、部分第三方导入的视频)可能会出现mediaType判断模糊的情况,这时候可以结合mediaSubtypes和duration做二次验证:
// 判断Live Photo(属于图片类型,但有特殊子类型) if asset.mediaType == .image && asset.mediaSubtypes.contains(.photoLive) { // 可以标记为图片,或者做特殊UI处理(比如加Live标签) } // 确保视频资源是有效视频 if asset.mediaType == .video { if asset.duration > 0 { // 确认是有效视频,加入视频数组 } else { // 无效视频,跳过处理 } }
三、UICollectionView单元格的视频标签展示
在单元格配置时,通过枚举判断类型,确保Video标签正确显示:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AssetCell", for: indexPath) as! AssetCell let currentAsset = assetArray[indexPath.item] cell.thumbnailImageView.image = currentAsset.thumbnail // 根据枚举判断是否显示Video标签 cell.videoBadgeLabel.isHidden = currentAsset.assetType != .video return cell }
总结
核心思路就是放弃字符串类型的资源判断,改用PHAsset原生的枚举和属性,这样能极大降低类型判断的误差,同时通过子类型、时长等属性做二次校验,确保资源类型判断的准确性。
内容的提问来源于stack exchange,提问作者K.Wu
相关产品推荐
相关产品推荐

