当用户触摸集合视图单元格时,它会展开到全屏。然后,您单击一个x按钮,它会缩小回到集合视图中。
问题是,我调用collectionView.reloadItems()
,并且它仅在第一次调用单元格init函数。每次之后,它都会调用cellForItem(at: )
,后者会调用collectionView.dequeueReusableCell()
,但不会再次调用该单元格的init,这会使该单元格中的内容不显示。
使单元格全屏,然后按X键重新加载项目,并将其放回集合视图中的正常大小
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(),则代码可以正常工作。如果我尝试在单元格的init函数(或didMoveToSuperview())中调用cell.setup()
,则只能在第一次调用collectinView.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")
}
}
答案 0 :(得分:1)
这就是collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifierfor:)
的重点。要回收单元对象,而不是在用户滚动时分配和释放一大堆对象。
您需要自己调用setup()
,最好使用prepareForReuse()
方法,并提供单元格可能需要的任何新值。
如果您为指定的标识符注册了一个类,并且必须创建一个新的单元格,则此方法通过调用其
init(frame:)
方法来初始化该单元格。对于基于笔尖的单元格,此方法从提供的笔尖文件中加载单元格对象。如果现有单元可供重用,则此方法将改为调用该单元的prepareForReuse()
方法。
来自the documentation of UICollectionView.dequeueReusableCell(withReuseIdentifier:for:)