ios - UICollectionView 一些单元格既不是可见项也不是出队单元格

标签 ios swift3 uicollectionview

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

为简单起见,我将项目缩减为只包含必要的 Controller 和最小化的 Storyboard 。基本上,我有一个 NavigationController 作为包含 MainViewController 的 EntryPoint,它本身包含一个带有 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,我正在 iPhone 7+ 模拟器上进行测试使用 iOS 10.1

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

在此先感谢您的帮助和亲切的问候

基督徒

编辑:只是为了弄清楚我的问题:我正在寻找一些建议,以解决我的代码中的明显错误或访问既不在可见项目列表中也不在滚动期间出列的 UICollectionViewCells 的方法 - 可能有一种访问那些我 simplay 不知道的单元格的方法

最佳答案

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

collectionView?.isPrefetchingEnabled = false

或者您可以保持开启状态,但也可以:

  • 连接到 UICollectionViewDelegate 方法 didEndDisplayingwillDisplay知道细胞独立于cellForItemAt出现和消失;或者

  • 让单元格对某些 View Controller 属性执行一些 KVO,或者观察 View Controller 将启动的一些通知,以便了解是否更改它们的状态。

关于ios - UICollectionView 一些单元格既不是可见项也不是出队单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42262972/

相关文章:

ios - UICollectionView setLayout :animated: not preserving zIndex

ios - 是否可以在 uitableviewcontroller 或 uicollectionviewcontroller 中添加 UIView (Admob)

ios - 以编程方式向 View 添加事件指示器

ios - 如何使用适用于 IOS 的本地 linhpone SDK 编译 linphone

ios - 在 Swift 3 中使用选择器

ios - 无法将 'AppDelegate' 分配给 'UNUserNotificationCenterDelegate'

ios - Segue 不会执行 Swift

ios - 弹出复杂导航路径到根的建议(路径包括多个嵌套的 UINavigationControllers 和模态覆盖)

ios - 用一种颜色绘制多边形描边,用另一种颜色填充?

xcode - 使用 InstantiateViewController 传递数据