添加元素后数组为空:iOS中使用BSImagePicker选图后UICollectionView无法加载图片问题
问题分析与解决方案
你遇到的问题核心有两个关键点,咱们一步步拆解解决:
1. 错误实例化导致的数组空值问题
在NewPostImagesViewController的viewDidLoad里,你写了:
print("images loaded? \(CustomFeedNavigationBar(navigationController: navigationController!).selectedImages)")
这里你新建了一个完全独立的CustomFeedNavigationBar对象,而不是引用之前那个已经完成图片选择的实例。每个类的实例都有自己独立的属性空间,这个新实例的selectedImages自然是空的。
2. 异步加载与页面跳转的时机不匹配
PHImageManager.default().requestImage是异步操作——它会在后台加载图片,加载完成后才通过回调返回结果。但你在点击Gallery选项后,先调用selectImages()紧接着就push了页面,这时候图片还在加载中,甚至还没开始往数组里追加元素,跳转过去肯定拿不到数据。
修复步骤
第一步:给目标页面添加图片接收属性
先修改NewPostImagesViewController,让它能接收外部传递的图片数组:
class NewPostImagesViewController: UIViewController { // 新增属性,用来接收选中的图片 var selectedImages: [UIImage] = [] override func viewDidLoad() { super.viewDidLoad() // ... 其他初始化代码 print("images loaded? \(selectedImages)") // 直接用这个属性刷新你的collectionView collectionView.reloadData() } }
第二步:调整图片加载与页面跳转的时机
修改CustomFeedNavigationBar里的handleAdd和selectImages方法,把页面跳转逻辑放到所有图片加载完成之后:
首先,修改handleAdd里的Gallery动作,移除立刻push的代码:
actionSheet.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { action in self.selectImages() }))
然后重写selectImages,用计数器跟踪所有图片的加载状态,完成后再跳转:
func selectImages() { let imagePicker = ImagePickerController() rootVC?.presentImagePicker(imagePicker, select: { (asset) in }, deselect: { (asset) in }, cancel: { (assets) in }, finish: { (assets) in self.selectedImages = [] let options: PHImageRequestOptions = PHImageRequestOptions() options.deliveryMode = .highQualityFormat // 用计数器跟踪已加载完成的图片数量 var loadedImageCount = 0 let totalImageCount = assets.count for asset in assets { PHImageManager.default().requestImage(for: asset, targetSize: PHImageManagerMaximumSize, contentMode: .aspectFit, options: options) { (image, info) in guard let validImage = image else { loadedImageCount += 1 return } self.selectedImages.append(validImage) print("images appended? \(self.selectedImages) YES") loadedImageCount += 1 // 所有图片加载完成后,再跳转并传递数据 if loadedImageCount == totalImageCount { let targetVC = NewPostImagesViewController() targetVC.hidesBottomBarWhenPushed = true // 把选中的图片数组传递给目标页面 targetVC.selectedImages = self.selectedImages self.navigationController.pushViewController(targetVC, animated: true) } } } }) }
第三步:清理无用代码
你在CustomFeedNavigationBar里声明的:
var collectionView = NewPostImagesViewController().collectionView
这行代码完全没必要,它会创建一个多余的NewPostImagesViewController实例,直接删掉即可——目标页面的collectionView应该由它自己管理。
额外提示
- 处理
PHImageManager.requestImage时,一定要用guard判断图片是否有效,避免强制解包(image!)导致崩溃。 - 如果需要支持图片取消选择的逻辑,记得同步更新
selectedImages数组。
内容的提问来源于stack exchange,提问作者Russ
相关产品推荐
相关产品推荐

