App首次获取相册权限后启动,CollectionView不显示照片的问题求助
嘿,我之前帮好几个开发者解决过一模一样的问题!核心原因很简单:你在首次获取相册权限后,没有及时触发照片数据的加载和CollectionView的刷新操作。
咱们来拆解一下问题:
- App首次启动时,
viewDidLoad里可能已经请求了权限,但这时候用户还没点击允许,所以你加载照片的逻辑要么没执行,要么执行时权限还没通过,导致photos数组是空的。 - 当用户授权后,你的代码没有监听这个状态变化并重新拉取数据,所以CollectionView一直显示空内容;而重启App后,权限已经存在,启动时就能正常加载数据,所以照片就显示出来了。
下面是针对你代码的修复方案,我直接给你改好的核心逻辑:
第一步:把照片获取逻辑抽成独立方法
这样不管是首次授权还是后续需要刷新,都能复用这个方法:
private func fetchPhotos() { let fetchOptions = PHFetchOptions() // 按创建时间倒序排列,符合用户浏览习惯 fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] // 只获取图片类型的相册资源 let fetchResult = PHAsset.fetchAssets(with: .image, options: fetchOptions) self.photos.removeAll() fetchResult.enumerateObjects { asset, _, _ in self.photos.append(asset) } }
第二步:在权限回调里触发数据加载和UI刷新
权限请求是异步的,用户点击允许后会进入回调,这时候你需要回到主线程(UI操作必须在主线程)执行刷新:
private func checkPhotoPermissions() { PHPhotoLibrary.requestAuthorization { [weak self] status in guard let self = self else { return } switch status { case .authorized: // 权限通过,立即拉取照片并刷新CollectionView DispatchQueue.main.async { self.fetchPhotos() self.collectionView.reloadData() } case .denied, .restricted: // 处理权限被拒的情况,给用户友好提示 DispatchQueue.main.async { let alert = UIAlertController(title: "需要相册权限", message: "请前往设置开启相册权限,才能查看手机里的照片", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "知道了", style: .default)) self.present(alert, animated: true) } default: break } } }
第三步:确保在viewDidLoad里正确调用权限检查
在viewDidLoad里只需要调用权限检查方法,不用提前加载照片,因为权限没通过时加载也是无效的:
override func viewDidLoad() { super.viewDidLoad() // 初始化CollectionView的代理、数据源、注册cell等操作 setupCollectionView() // 检查相册权限 checkPhotoPermissions() }
额外提醒
- 记得在
Info.plist里添加NSPhotoLibraryUsageDescription字段,否则权限请求会直接被系统拒绝 - 如果你的CollectionView用了自定义cell,确保在
cellForItemAt里正确用PHImageManager加载图片,避免出现空cell的情况
这样修改后,用户首次授权相册权限后,CollectionView就会立刻加载并显示照片,不用再重启App啦!
内容的提问来源于stack exchange,提问作者TheRedCamaro3.0 3.0
相关产品推荐
相关产品推荐

