我有一个UICollection视图。这些东西可以有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视图时,我希望这样做,以便当用户点击"在UICell上,它将调出changeStatus()函数。如何在Delegate / DataSource代码中执行此操作?另外,如何保存"状态"每个单元格(如果我刷新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?
}
}
答案 0 :(得分:1)
获得所选单元格的引用后,您可以更改单元格的状态。
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as? NGSelectStashCell else {return}
cell.status = "Active"
cell.changeStatus()
}
如果要保存单元格的状态,则必须进行模型驱动,即单元格中发生的任何事情都必须保存到模型中,并且当集合视图尝试重用以前的单元格时,必须在单元格中反映相同的模型实例化细胞。
你已经有了一个ModelStash模型,让我们以正确的方式使用它。
struct AvailableStash {
var statusImage: UIImage?
var backgroundImage: UIImage?
var title: String?
var status: String
//Initilize properties properly
init(with status: String) {
self.status = status
}
}
您的收藏视图必须是模型驱动的。例如:
class DemoCollectionView: UICollectionViewController {
var availableStashes: [AvailableStash]?
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return availableStashes?.count ?? 0
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let stashCell = collectionView.dequeueReusableCell(withReuseIdentifier: "ngStashCell", for: indexPath) as! NGSelectStashCell
let item = availableStashes[indexPath.row]
stashCell.titleLabel.text = item
// stashCell.bgImage make image file with the same name as the name and change bg image to it.
stashCell.statusImage = item.statusImage
return stashCell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let cell = collectionView.cellForItem(at: indexPath) as? NGSelectStashCell else {return}
cell.status = availableStashes[indexPath.row].status
cell.changeStatus()
availableStashes[indexPath.row].status = cell.status
}
}
答案 1 :(得分:1)
不幸的是,解决方案比您想象的要复杂一些。集合视图可以排队并重用其单元以提高性能。这意味着滚动时单个单元格可能会用于多个对象。会发生什么事情,当你将改变第一个单元格上的状态并将滚动以便重复使用时,这个单元格将保留其状态,看起来好像另一个单元格已经改变了状态......
因此,您的真相来源必须始终是您的数据来源。无论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")
}
}
}
我希望这能解决你的问题。