swift - collectionView.dequeueReusableCell 不调用 Cell 的 init

标签 swift uicollectionview uicollectionviewcell uicollectionviewlayout reloaddata

当用户触摸 Collection View 单元格时,它会扩展到全屏。然后单击 x 按钮,它会缩小回 Collection View 。

问题是,我调用 collectionView.reloadItems() 并且它只在第一次调用 cells init 函数。之后每次它都会调用 cellForItem(at: ) 调用 collectionView.dequeueReusableCell(),但它不会再次调用单元格的初始化,这使得里面的东西单元格未显示。

使单元格全屏,然后按 X 重新加载项目并将其恢复为 Collection View 中的正常大小

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        guard let cell = collectionView.cellForItem(at: indexPath) as? CollectionViewCell else { return }

        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: [], animations: {
            self.navigationController?.setNavigationBarHidden(true, animated: true)

            // make cell full screen
            cell.frame = collectionView.bounds
            cell.superview?.bringSubviewToFront(cell)

            //disable scroll
            collectionView.isScrollEnabled = false

            // make overlay full screen
            cell.imageView.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)

            // show X button
            cell.showXBtn()

            cell.xBtn.onTapped = {
                // enable scroll
                collectionView.isScrollEnabled = true

                // shrink back to collection view
                collectionView.reloadItems(at: [indexPath])

                // hide x button
                cell.hideXBtn()

                // show navigation bar
                self.navigationController?.setNavigationBarHidden(false, animated: true)
            }
        }, completion: nil)     
    }

如果我在这里调用 cell.setup(),代码工作正常。如果我尝试在单元格的初始化函数(或 didMoveToSuperview())中调用 cell.setup(),它只会在第一次调用 collectionView.reloadItems() 时起作用。

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier,
                                                      for: indexPath) as! CollectionViewCell
        // setup cell. If I call it within the cell, it only works the first time I call collectionView.reloadItem()
        cell.setup()

        // ignore spelling error lol
        let image = UIImage(named: "bdyaFilter")!
        cell.imageView.image = image

        return cell
    }

我的手机。 init 仅在我第一次尝试重新加载项目时被调用

class CollectionViewCell: UICollectionViewCell {
    let imageView = UIImageView()
    let xBtn = XButton()

    override init(frame: CGRect) {
        super.init(frame: frame)
        // this is only called the first time i call collectionView.reloadItems()
       // setup()
    }
    func setup() {
        self.backgroundColor = .orange
        self.layer.cornerRadius = 15
        self.layer.masksToBounds = true

        addImageView()
        addXBtn()
        hideXBtn()
    }
    private func addImageView() {
        imageView.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
        self.addSubview(imageView)
    }
    func addXBtn() {
        xBtn.frame = CGRect(x: 25, y: 25, width: 30, height: 30)
        self.addSubview(xBtn)
    }    
    func hideXBtn() {
        xBtn.isHidden = true
    }  
    func showXBtn() {
        xBtn.isHidden = false
    } 

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

最佳答案

这就是 collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifierfor:) 的全部要点。回收单元格对象,而不是在用户滚动时分配和释放一大堆对象。

您需要自己调用 setup(),最好是从 prepareForReuse() 方法调用,并提供单元格可能需要的任何新值。

If you registered a class for the specified identifier and a new cell must be created, this method initializes the cell by calling its init(frame:) method. For nib-based cells, this method loads the cell object from the provided nib file. If an existing cell was available for reuse, this method calls the cell’s prepareForReuse() method instead.

来自 the documentation of UICollectionView.dequeueReusableCell(withReuseIdentifier:for:)

关于swift - collectionView.dequeueReusableCell 不调用 Cell 的 init,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57445469/

相关文章:

ios - 如何使用 UISearchBar 过滤 NSDictionary?

ios - UICollectionView 的弹性 header

ios - 容器 View 集合 VC 被父级的点击手势识别器阻止

ios - 图像未出现在 PFQueryCollectionViewController 中

ios - 单击 UICollectionCell 上的按钮执行 segue

ios - 无法在 collectionView 中调用 dequeueReusableCellWithReuseIdentifier(collectionView : collectionViewLayout: sizeForItemAtIndexPath)

C 头文件中的 Swift 数学函数

ios - 应用重新安装后 Firebase 消息传递不起作用

ios - 如何在swift 4的分页模式下使用 Collection View 中的垂直居中单元格?

ios - Xcode - xib 和自动布局的奇怪问题(xib 扩展到随机高度)