我有一个 UICollection View 。这些东西可以有 3 种状态:
- 主动
- 中性
- 无效
现在,这是 UICollectionViewCell 的代码:
class NGSelectStashCell: UICollectionViewCell {
var status: String = "Active"
@IBOutlet weak var statusImage: UIImageView!
@IBOutlet weak var bgImage: UIImageView!
@IBOutlet weak var titleLabel: UILabel!
func changeStatus()
{
switch status {
case "Active":
status = "Neutral"
//change bgImage
case "Neutral":
status = "Inactive"
//change bgImage
case "Inactive":
status = "Active"
//change bgImage
default:
print("No Status")
}
}
}
现在,当我声明 UICollection View 时,我想这样当用户“单击”UICell 时它会调用 changeStatus() 函数。我如何在委托(delegate)/数据源代码中执行此操作?另外,我如何保存每个单元格的“状态”(这样,如果我刷新 UICollectionView,它们不会全部返回到“事件”状态?
/*
////////// UICOLLECTIONVIEW FUNCTIONS ///////////
*/
extension NewOnlineGameVC: UICollectionViewDelegate, UICollectionViewDataSource
{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return availableStashes.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let stashCell = collectionView.dequeueReusableCell(withReuseIdentifier: "ngStashCell", for: indexPath) as! NGSelectStashCell
stashCell.titleLabel.text = availableStashes[indexPath.row]
// stashCell.bgImage make image file with the same name as the name and change bg image to it.
return stashCell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// code to toggle between active/neutral/inactive
// do I re-declare stashCell as! NGSelectStashCell? or what do I do?
}
}
最佳答案
不幸的是,解决方案比您想象的要复杂一些。 Collection View 可以排队并重用它们的单元格以提高性能。这意味着在滚动时单个单元格可能并且将会用于多个对象。将会发生的是,当您更改第一个单元格的状态并滚动以便它被重用时,该单元格将保留其状态并且看起来好像另一个单元格具有此更改后的状态...
因此,您的真实来源必须始终是您的数据来源。无论 availableStashes
包含什么,它都需要包含它的状态。因此,例如,如果您当前有 var availableStashes: [MyObject] = []
,您可以这样更改它:
typealias MySource = (status: String, object: MyObject)
var availableStashes: [MySource] = []
func setNewObjects(objects: [MyObject]) {
availableStashes = objects.map { ("Neutral", $0) }
}
现在您需要更新数据源中的对象,例如:
func changeStatusOfObjectAtIndex(_ index: Int, to newStatus: String) {
availableStashes[index] = (newStatus, availableStashes[index].object)
}
所以在媒体上你这样做:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
changeStatusOfObjectAtIndex(indexPath.row, to: <#Your new status here#>)
UICollectionView().reloadItems(at: [indexPath])
}
现在这将触发该特定单元格的重新加载,您现在可以像这样更新
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let stashCell = collectionView.dequeueReusableCell(withReuseIdentifier: "ngStashCell", for: indexPath) as! NGSelectStashCell
stashCell.dataObject = availableStashes[indexPath.row]
return stashCell
}
在单元格内:
var dataObject: NewOnlineGameVC.MySource {
didSet {
titleLabel.text = dataObject.object
switch dataObject.status {
case "Active":
//change bgImage
case "Neutral":
//change bgImage
case "Inactive":
//change bgImage
default:
print("No Status")
}
}
}
我希望这能解决您的问题。
关于ios - 调用 "didSelectItemAt"时从单元格内调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48183844/