集合视图单元格中正常状态的 UIButton 图像每四个单元格重复一次



>我正在尝试为位于 collectionView 单元格中的按钮正常状态设置图像。 按下按钮时,图像会发生变化。 问题是每四个单元格在按下按钮时重复与原始单元格相同的图像。 有没有办法不让它重复自己,当按下按钮时,它只针对那个单独的单元格?

这是代码:

class FavoritesCell: UICollectionViewCell {
var isFavorite: Bool = false
@IBOutlet weak var favoritesButton: UIButton!
@IBAction func favoritesButtonPressed(_ sender: UIButton) {
_ = self.isFavorite ? (self.isFavorite = false, self.favoritesButton.setImage(UIImage(named: "favUnselected"), for: .normal)) : (self.isFavorite = true, self.favoritesButton.setImage(UIImage(named: "favSelected"), for: .selected))
}
}

我试过这样做,但由于某种奇怪的原因,即使按下按钮,"选定的"状态图像也永远不会显示:

let button = UIButton()
override func awakeFromNib() {
super.awakeFromNib()
button.setImage(UIImage(named: "favUnselected"), for: .normal)
button.setImage(UIImage(named: "favSelected"), for: .selected)
}

每次您的小区取消排队时,都会被调用cellForItemAt。这是您配置单元格数据的位置。因此,如果您需要显示标记为收藏夹的单元格,可以在此处进行。

那你怎么做呢?假设一开始没有选择所有单元格。好。你不必用cellForItemAt说什么.现在,假设您将几个单元格标记为收藏夹。这里发生的事情是,当单元格可见时,它将反映更改,因为按钮被挂钩到将进行更改的选择器。

现在问题来了。当您滚动并且单元格消失时,有关您的单元格被标记为收藏的信息将丢失!因此,您需要做的是维护一个数组,该数组将存储所有选定单元格的IndexPath。(确保在从收藏夹中删除单元格时删除IndexPath!我们称该数组为favourites。如果可以将集合视图的数据源用于存储选定的状态信息,那也可以。现在,您必须在按钮选择器中存储有关单元格是否标记为收藏夹的信息。

@objc func buttonTapped() {
if favourites.contains(indexPath) {   // Assuming you store indexPath in cell or get it from superview
favourites.removeAll(where: {$0 == indexPath})
} else {
favourites.append(indexPath)
}
}

存储有关单元格的信息后,每次取消单元排队时,都需要检查IndexPath是否favourites。如果是,则调用将单元格设置为选定状态的方法。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// Dequeue cell and populating cell with data, etc
if favourites.contains(indexPath) {
cell.showFavourite()
}
}

做?不!现在我们又遇到了另一个问题。此问题与单元格的重用有关。那么cellForItemAt到底发生了什么呢?您可以取消单元格的排队并使用它来显示信息。因此,当您取消排队时,发生的情况是,它可能已经用于在其他索引路径中显示一些其他信息。因此,那里存在的所有数据都将保留下来。(这就是为什么您有收藏夹每 4 个单元格重复一次的问题!

那么我们如何解决这个问题呢?UICollectionViewCell中有一个方法在单元格取消排队之前调用 -prepareCellForReuse。您需要在单元格中实现此方法并从单元格中删除所有信息,以便在到达时它是新鲜的cellForItemAt.

func prepareForReuse() {
//Remove label text, images, button selected state, etc
}

或者,您始终可以在cellForItemAt中设置单元格内所有内容的每个值,以便始终使用必要的值覆盖每个信息。

编辑:OP说他在集合视图中有一个集合视图。您可以像这样确定调用哪个集合视图,

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView === favoriteCollectionView { // This is the collection view which contains the cell which needs to be marked as favourite
// Dequeue cell and populating cell with data, etc
if favourites.contains(indexPath) {
cell.showFavourite()
}
return cell
}
// Dequeue and return for the other collectionview
}

该单元格很可能被重复使用,并且您的isFavorite设置为true

只需尝试添加

func prepareForReuse() {
super.prepareForReuse()
self.isFavorite = false
}

这会在重复使用单元格时将按钮设置为原始图像。

另外,既然你的按钮有两种状态selected为什么要跳这个舞

_ = self.isFavorite ? (self.isFavorite = false, self.favoritesButton.setImage(UIImage(named: "favUnselected"), for: .normal)) : (self.isFavorite = true, self.favoritesButton.setImage(UIImage(named: "favSelected"), for: .selected))

你只能说self.favoritesButton.selected = self.isFavorite

将您的手机代码更改为:

class FavoritesCell: UICollectionViewCell {
@IBOutlet weak var favoritesButton: UIButton!
var isFavorite: Bool = false {
didSet {
favoritesButton.selected = isFavorite
}
}
@IBAction func favoritesButtonPressed(_ sender: UIButton) {
favoritesButton.selected = !favoritesButton.selected       
}
override func prepareForReuse() {
super.prepareForReuse()
isFavorite = false
}
}

相关内容

最新更新