我的 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
方法didEndDisplaying
和willDisplay
知道细胞独立于cellForItemAt
出现和消失;或者让单元格对某些 View Controller 属性执行一些 KVO,或者观察 View Controller 将启动的一些通知,以便了解是否更改它们的状态。
关于ios - UICollectionView 一些单元格既不是可见项也不是出队单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42262972/