Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/110.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 从单元内调用函数时;didSelectItemAt";被称为_Ios_Swift_Xcode_Uicollectionview - Fatal编程技术网

Ios 从单元内调用函数时;didSelectItemAt";被称为

Ios 从单元内调用函数时;didSelectItemAt";被称为,ios,swift,xcode,uicollectionview,Ios,Swift,Xcode,Uicollectionview,我对事物有一种独特的看法。这些东西可以有3种状态: -活动的 -中性 -不活动的 现在,以下是UICollectionViewCell的代码: class NGSelectStashCell: UICollectionViewCell { var status: String = "Active" @IBOutlet weak var statusImage: UIImageView! @IBOutlet weak var bgImage: UIImageView!

我对事物有一种独特的看法。这些东西可以有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()函数。如何在委托/数据源代码中执行此操作?。另外,如何保存每个单元格的“状态”(以便在刷新UICollectionView时,它们不会全部返回到“活动”状态)


获得选定单元格的引用后,可以更改单元格的状态

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    guard let cell = collectionView.cellForItem(at: indexPath) as? NGSelectStashCell else {return}
    cell.status = "Active"
    cell.changeStatus()
}
如果要保存单元格的状态,则它必须是模型驱动的,即单元格发生的任何情况都必须保存到模型中,并且当集合视图尝试重用以前实例化的单元格时,必须在单元格中反射相同的模型

你已经有了一个可用的模型,让我们以正确的方式使用它

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
  }
}

获得选定单元格的引用后,可以更改单元格的状态

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    guard let cell = collectionView.cellForItem(at: indexPath) as? NGSelectStashCell else {return}
    cell.status = "Active"
    cell.changeStatus()
}
如果要保存单元格的状态,则它必须是模型驱动的,即单元格发生的任何情况都必须保存到模型中,并且当集合视图尝试重用以前实例化的单元格时,必须在单元格中反射相同的模型

你已经有了一个可用的模型,让我们以正确的方式使用它

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
  }
}

不幸的是,解决方案比您想象的要复杂一些。集合视图可能会排队并重用它们的单元格以提高性能。这意味着在滚动时,单个单元格可能并将用于多个对象。将发生的情况是,当您更改第一个单元格的状态并滚动时,它将被重用,然后再使用此单元格将保留其状态,并且看起来好像另一个单元格已更改此状态

所以你的真相来源必须始终是你的数据来源。无论
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])
}
在牢房里:

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")
        }
    }
}

我希望这能解决您的问题。

不幸的是,解决方案比您想象的要复杂一些。集合视图可能会排队并重用它们的单元格以提高性能。这意味着在滚动时,单个单元格可能也将用于多个对象。当您更改第一个单元格的状态并将croll这样它就被重用了,那么这个单元将保持它的状态,并且看起来好像另一个单元已经改变了状态

所以你的真相来源必须始终是你的数据来源。无论
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])
}
在牢房里:

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")
        }
    }
}
我希望这能澄清你的问题