【发布时间】:2017-03-04 17:55:31
【问题描述】:
在 iOS 10.0 上,UICollectionView 默认预取单元格。这导致准备在屏幕上显示但被隐藏的单元格。这个question 描述得非常好。
以下代码将在其单元格可见或根本不存在时成功取消选择索引路径。如果单元格存在且被隐藏,则索引路径将被取消选中,但单元格会一直停留在选中状态,直到被重用。
collectionView!.deselectItem(at: indexPath, animated: false)
在 iOS 9 上或在 iOS 10.0 上使用 isPrefetchingEnabled = false 禁用预取时,此问题不会出现。
这是 UICollectionView 中的错误还是我误解了 deselectItem 应该如何工作?
这是 UICollectionViewController 子类的完整代码,它通过以下步骤演示了此行为:
- 点击一个单元格,使其被选中(红色)
- 将单元格滚动到屏幕外
- 点击“取消选择单元格”按钮
- 在屏幕上滚动单元格
- 观察它看起来仍然被选中
- 点击另一个单元格
- 观察两个单元格看起来如何被选中
- 将第一个单元格滚动到屏幕外并再次返回
- 观察第一个单元格最终没有被选中
import UIKit
private let reuseIdentifier = "Cell"
class CollectionViewController: UICollectionViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
let button = UIButton(frame: CGRect(x: 10, y: 30, width: 360, height: 44))
button.backgroundColor = #colorLiteral(red: 0.9686274529, green: 0.78039217, blue: 0.3450980484, alpha: 1)
button.setTitleColor(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), for: .normal)
button.setTitleColor(#colorLiteral(red: 0.05882352963, green: 0.180392161, blue: 0.2470588237, alpha: 1), for: .highlighted)
button.setTitle("Deselect Cell", for: .normal)
button.addTarget(self, action: #selector(CollectionViewController.buttonPress), for: .touchUpInside)
view.addSubview(button)
}
func buttonPress() {
for indexPath in collectionView!.indexPathsForSelectedItems ?? [IndexPath]() {
let cell = collectionView!.cellForItem(at: indexPath)
NSLog("Deselecting indexPath: %@, cell: %@", indexPath.description, cell?.frame.debugDescription ?? "not visible")
collectionView!.deselectItem(at: indexPath, animated: false)
}
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 300
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
cell.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
cell.selectedBackgroundView = UIView(frame: cell.bounds)
cell.selectedBackgroundView!.backgroundColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
return cell
}
}
【问题讨论】:
标签: uicollectionview swift3 xcode8 ios10