UICollectionView 问题中的项目数

Numbers Of Items in UICollectionView issue

我有一个 UICollectionView 只有 1 个部分,但它有 2 个自定义 UICollectionViewCell。单元格的主要用途是显示用户在上一个 UIViewController 中选择的媒体(主要是图像)。单元格 1 始终首先显示,并且不会改变。它用于让用户能够单击它并在 UICollectionView 中添加更多照片。另一个单元格 2 用于显示所有图像。现在,单元格的数量会因以下因素而异:

1) 用户使用相机拍照(然后

2) 用户选择了多个 PHAssets 被转换为 UIImage 并显示在单元格中。

在这两种情况下,都会显示单元格 1。问题在于显示包含所有图像的数组中的项目数。如果我从相机胶卷中选择了 4 个资产,我总是会得到 3 个图像(而不是 4 个!)。我认为这是因为我在 numberOfItemsInSection 方法中设置 UICollectionView 时 return assets.count。 这当然会切断数组的最后一个图像,因为单元格 1 使用它 space。

我试过 return assets.count + 1 但是当 PHAssets 变成图像时它崩溃了,它说

Index out of range

我不知道我做错了什么。这是代码:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
        // Add More Photos Cell
        if indexPath.item == 0
        {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AddMorePhotosCell", for: indexPath) as! AddMorePhotosCell
            return cell
        }
        // Photos Cell
        else
        {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoPostCVCell", for: indexPath) as! PhotoPostCVCell
            if let takenImage = cameraPhotoUIImage
            {
                cell.cellImage.image = takenImage
            }
            if assets.count > 0
            {
                let asset = assets[indexPath.row]

                var imageRequestOptions: PHImageRequestOptions
                {
                    let options = PHImageRequestOptions()
                    options.version = .current
                    options.resizeMode = .exact
                    options.deliveryMode = .fastFormat
                    options.isSynchronous = true
                    return options
                }
                // TODO: Fix the size of the images. Right now it's 500x500
                let targetSize = CGSize(width: 500, height: 500)
                imageManager.requestImage(for: asset, targetSize: targetSize, contentMode: .aspectFill, options: imageRequestOptions)
                { (image, info) in
                    if image != nil
                    {
                        print(image!.size)
                        cell.cellImage.image = image
                        self.assetsTurnedIntoImages[indexPath.row] = image!
                        print("Assets turned into images is: ", self.assetsTurnedIntoImages.count)
                        // TODO: Fix Delete button - Right now it doesn't delete the right image from the cell, but the last one!

                        cell.deleteButton?.tag = indexPath.row
                        cell.deleteButton?.addTarget(self, action: #selector(self.deleteImage(sender:)), for: UIControlEvents.touchUpInside)
                    }
                }
            }
            return cell
        }
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        if assets.count > 0
        {
            return assets.count + 1
        }
        else
        {
            return 2
        }
    }

您需要调整数组索引。这样想:

  • 4 张图像的数组 = [A、B、C、D]
  • 第一个单元格不在数组中
  • 项目总数? 5
  • CollectionView 说 "Give me item 1" - 你 return FirstCell
  • CollectionView 说 "Give me item 2" - 你需要 return 数组的第一个元素,而不是第二个元素

所以...

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
        // Add More Photos Cell
        if indexPath.item == 0
        {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "AddMorePhotosCell", for: indexPath) as! AddMorePhotosCell
            return cell
        }
        // Photos Cell
        else
        {
            // offset the index by -1 for the FirstCell
            let asset = assets[indexPath.item - 1]

            // the rest of the stuff
        }

     }

希望清楚...

我想通了,但归功于@DonMag,因为他是对的。 首先,我认为 numberOfItemsInSection 需要是 array.count + 1 这一事实是正确的,因为我们需要为 Cell1 再添加一项。 所以,我们有:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
    if assets.count > 0
    {
        return assets.count + 1
    }
    else
    {
        return 2
    }
}

而且,重要的部分是 let asset = assets[indexPath.item - 1] 以及我们将每个 PHAsset 转换为图像的地方,即这一行:

self.assetsTurnedIntoImages[indexPath.item - 1] = image!