代码之家  ›  专栏  ›  技术社区  ›  SwiftyJD

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

  •  0
  • SwiftyJD  · 技术社区  · 7 年前

    我正在尝试为位于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)
    }
    
    2 回复  |  直到 7 年前
        1
  •  0
  •   Rakesha Shastri    7 年前

    每次你的手机 cellForItemAt

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

    现在问题来了。当你 纸卷 IndexPath 所有选定单元格的。(确保拆下 从收藏夹中删除单元格时!)我们称之为数组 favourites . 如果可以使用collection视图的数据源来存储选定的状态信息,也可以。现在,您必须在按钮选择器中存储有关单元格是否标记为收藏夹的信息。

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

    存储有关单元格的信息后,每次将单元格出列时,都需要检查 索引 最喜欢的 . 如果是,则调用将单元格设置为选定状态的方法。

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

    完成?不!现在我们有另一个问题。此问题与 重新使用 cellForItemAt公司 事实上?你呢 一个单元格并用它来显示信息。因此,当您将它出列时,它可能已经用于显示其他索引路径中的其他信息。所以所有现存的数据 坚持

    那我们怎么解决这个问题呢?有方法在里面 UICollectionViewCell 这就是所谓的 单元格已出列- prepareCellForReuse . 您需要在单元格中实现此方法,并从单元格中删除所有信息,以便当信息到达时是新鲜的 cellForItemAt公司 .

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

    或者你可以随时设置单元格中所有内容的值 所以每一个信息总是被必要的值覆盖。

    编辑: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
    }
    
        2
  •  0
  •   Ladislav    7 年前

    细胞很可能被重复使用,你的 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
        }
    }