ios - 调用 "didSelectItemAt"时从单元格内调用函数

标签 ios swift xcode uicollectionview

我有一个 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/

相关文章:

ios - Swift 如何在 Webview 中打开链接?

ios - 尝试从我的应用程序打开其他应用程序时出现 Swift 错误 |操作无法完成。 (操作系统状态错误-10814。)

c - 在 Xcode 中使用 C 的文件 I/O 时遇到问题

iOS 在动态表格的顶部创建一个静态单元格

ios - xcode 4.2:“为企业分发”按钮在哪里?

ios - 用户在APP中关闭通知时如何接收通知

ios - Xcode 6 与 Swift 超慢打字和自动完成

xcode - 如何仅播放一次声音 SWIFT

ios - Swift:将数组值添加到应用内电子邮件正文

iOS 图表框架 maximumFractionDigits 不工作