UICollectionView一些单元既不是可见项也不是出列单元格

时间:2017-02-16 01:00:29

标签: ios swift3 uicollectionview

我的UICollectionView中存在一个问题,其中某些单元格似乎既不是indexPathForVisibleItems的一部分,也不是来自dequeueReusableCell的缓存队列。结果是,某些单元格在滚动期间没有收到所需的数据更新并显示旧行为。

为简单起见,我将项目缩减为必要的控制器和最小化的故事板。基本上,我有一个NavigationController作为EntryPoint,它包含MainViewController,它本身包含一个带有CollectionViewController的ContainerView。

NavigationController使用默认编辑按钮在编辑和非编辑模式之间切换 - 这会导致在编辑模式下在单元格上显示图像。因此,我实现了setEditing并更改了所有可见单元格的图像隐藏属性,另外我在出列时设置了图像隐藏属性 - 假设单元格可见或将来会出列。

这在CollectionView从上到下滚动时工作正常。但是当我从编辑模式切换回非编辑模式同时滚动到底部然后滚动回到顶部时,一些单元仍然显示图像(更具体:至少相同的行,这是第一个非可见行)。不知怎的,我假设出列的单元格和可见单元格将是显示数据的互补部分,这应该导致图像在setEditing调用期间隐藏/取消隐藏(适用于前4个出列的单元格)或在出列时隐藏/取消隐藏(适用于最后几行,除了我的例子中的第三行)

CollectionViewController的代码:

import Foundation
import UIKit
import Photos
class CollectionViewController : UICollectionViewController {

    fileprivate let CELL_ID = "PicCell"
    fileprivate let IMAGE_VIEW_SIZE = 104
    var selectedIndex = -1
    var itemCount = 28

    override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: animated)
        print(self.isEditing)
        collectionView?.allowsMultipleSelection = editing
        for indexPath in (collectionView?.indexPathsForSelectedItems)! {
            collectionView?.deselectItem(at: indexPath, animated: true)
        }

        for indexPath in (collectionView?.indexPathsForVisibleItems)! {
            let cell = collectionView?.cellForItem(at: indexPath) as? PicCell
            if cell != nil {
                cell?.editing = editing
            }
        }
    }

    override func viewDidLoad() {
        self.navigationItem.rightBarButtonItem = self.editButtonItem
        collectionView?.reloadData()
    }
}

extension CollectionViewController {
    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return itemCount;
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        print(indexPath.row)
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CELL_ID, for: indexPath) as! PicCell
        cell.editing = isEditing
        cell.isSelected = false
        return cell;
    }
}

PicCell代码

import Foundation
import UIKit
class PicCell : UICollectionViewCell {

    @IBOutlet weak var deleteBtn: UIImageView!
    var editing:Bool = false{
        didSet {
            self.deleteBtn.isHidden = !editing
            self.deleteBtn.tintColor = UIColor.blue
        }
    }

    override var isSelected: Bool{
        didSet {
            if isSelected  && editing {
                self.deleteBtn.tintColor = UIColor.red
            } else {
                self.deleteBtn.tintColor = UIColor.blue
            }
        }
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        self.editing = false
        self.isSelected = false
    }
}

MainViewController的代码

import Foundation
import UIKit
class MainViewController: UIViewController {

    override func viewDidLoad() {
        self.navigationItem.rightBarButtonItem = self.editButtonItem
    }

    override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: animated)
        collectionController?.setEditing(editing, animated: animated)
    }

    var collectionController : CollectionViewController? = nil
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "ShowCollectionView" {
            collectionController = segue.destination as! CollectionViewController
        }
    }
}

正如您所看到的,我在单个部分中使用常量值来计算项目数,这不应该是一个大问题。

我不知道它是否重要,但我的单元格的宽度和高度是104px,图像呈现为模板,UIContainerView的宽度为343,高度为473,我正在测试iOS 7的iPhone 7+模拟器

如果故事板中缺少任何内容,我可能会添加一些屏幕截图,但我不确定要准确发布什么

提前感谢您的帮助和亲切的问候

基督教

编辑:只是为了清楚我的问题:我正在为我的代码中的明显错误或访问UICollectionViewCells寻找一些建议,这些UICollectionViewCell既不在可见项列表中也不在滚动期间出列 - 那里可能是一种访问那些我不知道的细胞的方法

1 个答案:

答案 0 :(得分:5)

如果您关闭预取,则可以更改此行为:

collectionView?.isPrefetchingEnabled = false

或者你可以保持它,但随后:

  • 挂钩UICollectionViewDelegate方法didEndDisplayingwillDisplay以了解细胞的出现和消失,与cellForItemAt无关;或

  • 让单元格在某些视图控制器属性上执行某些KVO,或观察视图控制器将启动的一些通知,以了解是否更改其状态。

相关问题