Search code examples
iosswift3uicollectionviewuicollectionviewcellselectedindex

why selected cell in collection view doesn't show correctly in the UICollection View Swift 3?


I am using swift 3 and I have collection view in my app that shows iPhone gallery in that . every things are good But I want the user could select some photos and this can be happen But the problem is that I used another small image in every cells that when the user select that cell the picture will showing a tick that user could understand that cell has been selected - this will work at the beginning but when the user scroll the collection view some cells that user didn't select them has this tick too! **Remember that select and did deselect are working well and the problem is just for showing this tick ** **I have image with tag in cell and that image will showing a tick or nothing when the user select the cell or didDeselect that **

I know that these codes are more than you think But many some Guys need to access all of the codes so you can see my codes below

 import UIKit
 import Photos
 class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
let arr_img = NSMutableArray()

@IBOutlet var collview: UICollectionView!

override func viewDidLoad() {
    super.viewDidLoad()
    let allPhotosOptions : PHFetchOptions = PHFetchOptions.init()
    allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
    let allPhotosResult = PHAsset.fetchAssets(with: .image, options: allPhotosOptions)
    allPhotosResult.enumerateObjects({ (asset, idx, stop) in

        self.arr_img.add(asset)
    })

}
func getAssetThumbnail(asset: PHAsset, size: CGFloat) -> UIImage {
    let retinaScale = UIScreen.main.scale
    let retinaSquare = CGSize(width: size * retinaScale, height: size * retinaScale)//CGSizeMake(size * retinaScale, size * retinaScale)
    let cropSizeLength = min(asset.pixelWidth, asset.pixelHeight)
    let square = CGRect(x: 0, y: 0, width: cropSizeLength, height: cropSizeLength)//CGRectMake(0, 0, CGFloat(cropSizeLength), CGFloat(cropSizeLength))
    let cropRect = square.applying(CGAffineTransform(scaleX: 1.0/CGFloat(asset.pixelWidth), y: 1.0/CGFloat(asset.pixelHeight)))

    let manager = PHImageManager.default()
    let options = PHImageRequestOptions()
    var thumbnail = UIImage()

    options.isSynchronous = true
    options.deliveryMode = .highQualityFormat
    options.resizeMode = .exact
    options.normalizedCropRect = cropRect

    manager.requestImage(for: asset, targetSize: retinaSquare, contentMode: .aspectFit, options: options, resultHandler: {(result, info)->Void in
        thumbnail = result!
    })
    return thumbnail
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

//MARK:
//MARK: Collectioview methods
func collectionView(_ collectionView: UICollectionView,
                    numberOfItemsInSection section: Int) -> Int {
    return arr_img.count
}
func collectionView(_ collectionView: UICollectionView,
                    cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell",
                                                  for: indexPath)
    let imgview : UIImageView = cell.viewWithTag(20) as! UIImageView
    imgview.image = self.getAssetThumbnail(asset: self.arr_img.object(at: indexPath.row) as! PHAsset, size: 150)

    return cell
}

}

 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
 let cell = collectionView.cellForItem(at: indexPath as IndexPath)
    if cell!.isSelected == true {


        print(indexPath)
        cell?.backgroundColor = UIColor.orange
        print("Cell is Selected!")
        let selectView : UIImageView = cell?.viewWithTag(22) as! UIImageView
        selectView.image = UIImage(named: "Select.png")
    }

    else if cell!.isSelected != true        {

        collectionView.cellForItem(at: indexPath as IndexPath)

    cell?.backgroundColor = UIColor.clear
        let selectView : UIImageView = cell?.viewWithTag(22) as! UIImageView
        selectView.image = nil

        print("Cell is  Not Selected!")

    }

}

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath as IndexPath)

    print(indexPath)
    if cell?.isSelected == true {
        cell?.backgroundColor = UIColor.orange
        print("Cell is Selected In Deselect!")
        let selectView : UIImageView = cell!.viewWithTag(22) as! UIImageView
        selectView.image = nil
        collectionView.cellForItem(at: indexPath as IndexPath)

    }
    else if cell?.isSelected != true        {
        cell?.backgroundColor = UIColor.clear
        collectionView.cellForItem(at: indexPath as IndexPath)

        print("Cell is DeSelected!")
        let selectView : UIImageView = cell!.viewWithTag(22) as! UIImageView
        selectView.image = nil


    }

}

Solution

  • Just take a button inside your cell and give tag to it.

    Take array and do following.

    let arr_selected = NSMutableArray()
    

    func collectionView(_ collectionView: UICollectionView,
                            cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell",
                                                          for: indexPath)
    
            let btn_check : UIButton = cell.viewWithTag(30) as! UIButton
            if arr_selected.contains(indexPath.row){
                btn_check.isSelected = true
            }else{
                btn_check.isSelected = false
            }
            return cell
        }
        func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){
            if arr_selected.contains(indexPath.row){
                arr_selected.remove(indexPath.row)
            }else{
                arr_selected.add(indexPath.row)
            }
            self.collview.reloadData()
        }
    

    if you want demo, then you can download from HERE