Флажки в CollectionView меняют позиции при прокрутке - PullRequest
0 голосов
/ 29 августа 2018

У меня есть collectionView (3 * 3) с изображениями, которые я загружаю с сервера, и я поместил флажок в верхнем левом углу каждой ячейки, чтобы я мог выбрать ячейки, и на основе выбранных я получу идентификаторы для соответствующие изображения клеток (идентификаторы, поступающие с сервера), и я могу сделать все правильно. Но проблема в том, что если есть 20 изображений, и если я проверяю 5 случайных ячеек, которые загружаются в первый раз, и когда я прокручиваю вниз, чтобы выбрать другие ячейки, 5 других случайных флажков уже проверены, и если я снова прокручиваю вверх некоторые другие Проверено 5 случайных клеток. Похоже, что отмеченные флажки меняют позиции из-за свойства повторного использования в очереди в cellForItemAtIndexPath метода UICollectionView DataSource ..

Понятия не имею, как преодолеть эту проблему. Пожалуйста, помогите мне, если кто-нибудь знает, как это сделать. Я публикую ниже код, который я написал до сих пор, и некоторые скриншоты симулятора для лучшего понимания проблемы ...

EditCertificatesViewController:

import UIKit
import Alamofire

protocol CheckBoxState {
    func saveCheckBoxState(cell: EditCertificateCell)
}

class EditCertificatesViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {

    @IBOutlet weak var certificatesCollectionView: UICollectionView!

    var certificatesArray = [Certificates]()

     override func viewDidLoad() {
         super.viewDidLoad()
         self.title = "Delete Certificates"
         navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
     }

     func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

         return certificatesArray.count
     }

     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "editCertificate", for: indexPath)  as! EditCertificateCell
         if let certificateURL = URL(string: certificatesArray[indexPath.item].imagePath) {
             cell.certificateImage.af_setImage(withURL: certificateURL)
         }
         cell.certificateId.text = "\(certificatesArray[indexPath.item].imageId)"
         cell.selectCertificate.customBox()
         if selectedCellIndex.contains(indexPath.item) {
             cell.selectCertificate.on = true
         } 
         else {
             cell.selectCertificate.on = false
         }
         cell.selectCertificate.tag = indexPath.item
         cell.checkState = self
         return cell
       }
}

extension EditCertificatesViewController: CheckBoxState {

    func saveCheckBoxState(cell: EditCertificateCell) {

        if cell.selectCertificate.on == true {
            cell.selectCertificate.on = false
        } 
        else {
            cell.selectCertificate.on = true
        }

        if selectedCellIndex.contains(cell.selectCertificate.tag) {
            selectedCellIndex = selectedCellIndex.filter{$0 != cell.selectCertificate.tag}
        } 
        else {
            selectedCellIndex.append(cell.selectCertificate.tag)
        }
        print("Status1 \(selectedCellIndex.sorted { $0 < $1 })")
        //        certificatesCollectionView.reloadData()
    }
}

EditCertificateCell:

import UIKit

class EditCertificateCell: UICollectionViewCell {

    @IBOutlet weak var certificateImage: UIImageView!
    @IBOutlet weak var selectCertificate: BEMCheckBox!
    @IBOutlet weak var certificateId: UILabel!
    @IBOutlet weak var selectCertificateBtn: UIButton!

    var checkState: CheckBoxState?

    override func awakeFromNib() {
        super.awakeFromNib()
        self.selectCertificateBtn.addTarget(self, action: #selector(btnTapped(_:event:)), for: .touchUpInside)
    }

    @objc func btnTapped(_ sender: UIButton,event: UIEvent) {
        self.checkState?.saveCheckBoxState(cell: self)
    } 
}

Ответы [ 3 ]

0 голосов
/ 29 августа 2018

CollectionView dequeue - ваша клетка. Чтобы избавиться от этого, вам нужно поддерживать массив выбранных сертификатов. Выполните следующую процедуру.

  1. Создать массив arrSelectedIndex : [Int] = []

  2. В cellForRow,

    • Сначала проверьте, доступен ли текущий индекс в arrSelectedIndex или нет? Если да, то сделайте вашу ячейку как выбранное, иначе не снимайте флажок.

    • Присвойте тег вашей кнопке чека следующим образом buttonCheck.tag = indexPath.item

  3. Если вы хотите выбрать изображения для действия кнопки проверки, выполните следующие действия.

    • Получить тэг кнопки let aTag = sender.tag
    • Теперь проверьте, доступен ли этот индекс в arrSelectedIndex или нет? Если да, то удалите этот индекс из arrSelectedIndex, иначе добавьте этот массив.
    • перезагрузите свою ячейку сейчас.
  4. Если вы хотите выбрать изображения при действии кнопки проверки didSelectItem, выполните следующие действия.

    • Теперь проверьте, доступен ли этот выбранный индекс (indexPath.item) в arrSelectedIndex или нет? Если да, то удалите этот индекс из arrSelectedIndex, в противном случае добавьте этот массив.
    • перезагрузите вашу ячейку сейчас.

Поскольку эта процедура длительная, я могу только объяснить вам, как это сделать. Если вам нужна дополнительная помощь, вы можете спросить.

0 голосов
/ 29 августа 2018

Создать массив var Status1CheckList = [Int]()

А в cellForItemAt indexPath проверьте состояние как

if Status1CheckList.contains(indexPath.row) {
    cellOfCollection.CheckBtn.setImage(UIImage(named: "check"), for: .normal)
} else {
    cellOfCollection.CheckBtn.setImage(UIImage(named: "uncheck"), for: .normal)
}
cellOfCollection.CheckBtn.tag = indexPath.row
cellOfCollection.CheckBtn.addTarget(self, action: #selector(self.checkList), for: .touchUpInside)

И метод контрольного списка, После нажатия кнопки перезагрузить коллекцию просмотра

 @objc func checkList(_ sender: UIButton) {
        if Status1CheckList.contains(sender.tag) {
            Status1CheckList =  Status1CheckList.filter{ $0 != sender.tag}
        } else {
            Status1CheckList.append(sender.tag)
        }
        print("Status1 \(Status1CheckList.sorted { $0 < $1 })")
    self.collectionviewObj.reloadData()
}
0 голосов
/ 29 августа 2018

Это ожидается. Потому что вы снова используете клетки.

Учтите это. Вы выбираете первые 2 ячейки, а теперь прокручиваете вниз. Эта ваша функция будет называться func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {. Теперь это может получить представления из первых двух ячеек, которые вы выбрали, и их флажки уже установлены.

Вам необходимо сбросить их и установить в зависимости от их последнего состояния.

Я бы порекомендовал добавить еще одно свойство isCertificateSelected к вашей Certificate модели. Каждый раз, когда пользователь нажимает на ячейку, вы извлекаете модель и устанавливаете / отменяете это bool. Когда вызывается collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath), вы снова получаете isCertificateSelected и соответственно устанавливаете флажок.

...