我有collectionView(3 * 3),其中包含我要从服务器加载的图像,并且在每个单元格的左上角放置了一个复选框,以便我可以选择这些单元格,并根据选定的单元格获取ID各个单元格的图像(来自服务器的ID),并且我能够正确执行所有操作。但是,问题是是否有20张图像,并且如果我检查第一次加载的5个随机单元格,并且当我向下滚动以选择其他单元格时,已经检查了5个其他随机复选框,并且如果我再次向上滚动其他一些检查5个随机单元。似乎由于UICollectionView DataSource方法的cellForItemAtIndexPath中的出队列可重用属性,选中的复选框正在更改位置。
我不知道如何克服这个问题。如果有人知道该怎么做,请帮助我。我将在到目前为止编写的代码和一些模拟器屏幕截图的下方发布,以更好地理解问题...
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()
}
}
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)
}
}
答案 0 :(得分:2)
CollectionView出队是您的单元格。要消除这一点,您需要维护一组选定的证书。请按照以下步骤操作。
创建一个数组arrSelectedIndex : [Int] = []
在cellForRow
中,
首先检查arrSelectedIndex
中可用的当前索引吗?如果是,则将您的单元格设置为选中状态,否则不要选中它。
像下面的buttonCheck.tag = indexPath.item
如果要在选中按钮操作中选择图像,请执行以下操作。
aTag = sender.tag
arrSelectedIndex
中可用吗?如果是,则从arrSelectedIndex
中删除该索引,否则追加该数组。如果要在didSelectItem即时检查按钮操作中选择图像,请执行以下操作。
arrSelectedIndex
中可用吗?如果是,则从arrSelectedIndex
中删除该索引,否则追加该数组。由于此过程很漫长,因此我只能向您解释如何执行此操作。如果需要进一步的帮助,您可以询问。
答案 1 :(得分:1)
这是预期的。因为您正在重用单元格。
考虑一下。您选择前2个单元格,然后向下滚动。您的此功能将称为func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
。现在,这可能会从您选择的前两个单元格中获取视图,并且它们的复选框也已被选中。
您需要取消设置它们,并根据它们的最后状态对其进行设置。
我建议向您的isCertificateSelected
模型添加另一个属性Certificate
。每次用户点击一个单元格时,您都会检索模型,并设置/取消设置此bool
。调用collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath)
时,您再次检索isCertificateSelected
,并相应地设置了复选框。
答案 2 :(得分:1)
创建一个数组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)
和清单方法,选择按钮后重新加载collectionview
@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()
}