web-dev-qa-db-ja.com

リロード時にUICollectionViewCellをクリアする方法は?

UICollectionViewに表示されるデータがラベルを上書きし、セルビューがクリアされないという問題があります。

この画像は問題を示しています、

IE:

UICollectionViewCell data is not getting cleared

そのように構築された私のUICollectionViewCell;

// in viewDidLoad
self.playerHUDCollectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier:reuseIdentifer)

 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell:UICollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifer, for: indexPath) as UICollectionViewCell

        let arr = UINib(nibName: "EYPlayerHUDView", bundle: nil).instantiate(withOwner: nil, options: nil)
        let view = arr[0] as! EYPlayerHUDView
        cell.contentView.addSubview(view)

        if let allPlayers = self.allPlayers
        {
            let player:EYPlayer = allPlayers[indexPath.row]
            view.updatePlayerHUD(player: player)
        }

        cell.layoutIfNeeded()

        return cell
    }

ビューを使用してセルに表示します。

cellForItemAt内のすべてのセルのサブチャイルドを削除しようとしましたが、すべてのサブビューが削除されているようです。

上記の例のようにUICollectionViewCellのラベルやその他の情報が汚れないように、UICollectionViewCellをクリアする方法を知りたいです。

どうもありがとう

7
zardon

次のように、カスタムセルクラスでprepareForReuseメソッドを使用します。

override func prepareForReuse() {
    super.prepareForReuse()
    //hide or reset anything you want hereafter, for example
    label.isHidden = true

}

cellForItemAtIndexPathで、カスタムセルをインスタンス化します。

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "myCellIdentifier", for: indexPath) as! CustomViewCell

次に、常にcellForItemAtIndexPathで、アイテムの可視性/値を設定します

12
carmine
//cell = UICollectionViewCell
for subview in cell.contentView.subviews {

     // you can place "if" condition to remove image view, labels, etc.
     //it will remove subviews of cell's content view
     subview.removeFromSuperview()

}
3
Mahendra

UICollectionViewCellsは、インスタンス化を回避し、パフォーマンスを最適化するために再利用されます。スクロールしてセルが非表示になった場合、同じオブジェクトが再び使用され(dequeueReusableCell)、新しいcontentcellForItemAt ..に設定されます。

前の回答で述べたように、セルを再利用する前に、prepareForReuse()がセルで呼び出されます。したがって、prepareForReuse()をオーバーライドして、必要な準備を行うことができます。

ただし、再利用するたびに新しいEYPlayerHUDViewを作成してセルに追加しているため、セルはスタックされたEYPlayerHUDViewsでいっぱいになります。

これを回避するには、UICollectionViewCellをサブクラス化し、EYPlayerHUDViewをカスタムセルのプロパティにします(XIBを使用することをお勧めします)。

class MyCell: UICollectionViewCell {
    @IBOutlet var player:EYPlayerHUDView!

    override func prepareForReuse() {
        super.prepareForReuse()
        // stop your player here
        // set your label text = ""
    }
}

その後、EYPlayerHUDViewcellForItemAtをインスタンス化せずに、また新しいビューとして追加せずに更新できます。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifer, for: indexPath) as? MyCell else {
        return nil
    }

    if let allPlayers = self.allPlayers {
        let player:EYPlayer = allPlayers[indexPath.row]
        cell.player.updatePlayerHUD(player: player)
    }

    return cell
}

(コードはテストされていません)

1
shallowThought

カスタムUICollectionViewクラスを作成し、prepareForReuseを実装して、必要に応じてコンテンツをクリアします。

0
sanjana