简体   繁体   English

UICollectionView CustomCell重用

[英]UICollectionView CustomCell ReUse

I am fetching user's Photo Asset and trying to create a custom UICollectionViewCell in my UICollectionView where the first index is a Camera Image and other cells are the Camera Images. 我获取用户的Photo Asset ,并试图创建一个自定义UICollectionViewCellUICollectionView其中第一个指标是Camera Image和其他细胞的摄像机图像。 But when I scroll, it's like the image at the index is recreated and I notice some images in my cell get the view I added at the index[0] 但是,当我滚动时,就像重新创建了索引处的图像,并且我注意到单元格中的某些图像获得了在index[0]处添加的视图。

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    //Deque an GridViewCell
    let cell: GridViewCell = (collectionView.dequeueReusableCellWithReuseIdentifier(CellReuseIdentifier, forIndexPath: indexPath) as? GridViewCell)!
    if indexPath.item != 0 {

        let asset = assetsFetchResults[indexPath.item - 1] as! PHAsset
        cell.representedAssetIdentifier = asset.localIdentifier

        imageManager.requestImageForAsset(asset, targetSize: AssetGridThumbnailSize, contentMode: PHImageContentMode.AspectFill, options: nil) { (result: UIImage?, info: [NSObject : AnyObject]?) -> Void in
            //print(result)
            if cell.representedAssetIdentifier.isEqualToString(asset.localIdentifier) {
                if let imageResult = result {
                    cell.imageView.image = imageResult
                }
            }
        }
    } else {
        let cameraButton = UIButton(frame: CGRectMake(0,0,80,80))
        cameraButton.setTitle("Camera", forState: .Normal)
        cameraButton.frame = cell.imageView.bounds
        cell.imageView.addSubview(cameraButton)
    }

    return cell
}

Below is an image for illustration 下面是用于说明的图像 错误的后继

Reusable cells are reused by the collection view when they are scrolled outside the view to prevent a lot of memory use. 当可重用单元在视图外滚动时,它们会被收集视图重用,以防止占用大量内存。 When a certain cell gets scrolled outside of the view the collection view will mark them as reusable. 当某个单元格滚动到视图外部时,集合视图会将它们标记为可重用。 Reusable cells will be reused by the collection view instead of creating new ones. 可重用的单元将被集合视图重用,而不是创建新的单元。 This will significantly reduce memory use. 这将大大减少内存使用。 Why would you keep 1000 cells in memory if only 20 of them fit on the screen at the same time. 如果只有20个单元同时显示在屏幕上,为什么还要在内存中保留1000个单元。

because cells are reused, they will still contain the content of previous cell, this means that the cell still has the cameraButton as a subview. 因为单元格已被重用,所以它们仍将包含先前单元格的内容,这意味着该单元格仍将cameraButton作为子视图。 Same story with the images, you need to manually remove them at from the cell and make sure al old content gets replaced or removed. 与图片的故事相同,您需要从单元格中手动删除它们,并确保替换或删除所有旧内容。

When you perform methods that will download and set the image to the cell after a while, the cell could still contain the image of the previous cell. 当您执行将下载图像并将图像设置到该单元格的方法之后,该单元格仍可能包含前一个单元格的图像。 You should clear the image at the beginning of the cellForRowAtIndexPath method to remove the old image/subviews. 您应该在cellForRowAtIndexPath方法的开头清除图像,以删除旧的图像/子视图。

See example below: 请参见下面的示例:

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! GridViewCell


    if indexPath.row == 0 {
        // Show the title becouse it's the first cell.
        cell.titleLabel.hidden = false

        // Title needs to be set in storyboard
        // Default image for camera roll needs to be set in storyboard

    } else {
        // All the other cells.
        cell.titleLabel.hidden = true

        // Clear old content
        cell.imageView.image = nil

        // I don't exactly know what all this code does behind the screen, but I assume it's a method that downloads the image and add it to the imageView when it's done.
        let asset = assetsFetchResults[indexPath.item - 1] as! PHAsset
        cell.representedAssetIdentifier = asset.localIdentifier

        imageManager.requestImageForAsset(asset, targetSize: AssetGridThumbnailSize, contentMode: PHImageContentMode.AspectFill, options: nil) { (result: UIImage?, info: [NSObject : AnyObject]?) -> Void in
            //print(result)
            if cell.representedAssetIdentifier.isEqualToString(asset.localIdentifier) {
                if let imageResult = result {
                    cell.imageView.image = imageResult
                }
            }
        }
}

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {

    // Cell that needs to open the camera roll when tapped)
    if indexPath.row == 0 {

        // Do something that opens the camera roll

    }

}

I didn't test this code, but it should be something similar to this. 我没有测试此代码,但应该与此类似。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM