[英]Swift CollectionView Reusable Cells Registering
我在UIViewcontroller
了CollectionView问题。 我从JSON获取数据,在特殊条件下,单元格似乎没有被正确重用,我认为我设置Collectionview的方式有问题。
概述:
我的MyCollectionViewCell.swift
:
import UIKit
class MyCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var bottomLabel: UILabel!
@IBOutlet weak var topLabel: UILabel!
}
如你所见,我的Cell中有两个标签。 我的Viewcontroller的部分内容:
import UIKit
private let reuseIdentifier = "colcel"
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
// Register cell classes
//collectionView.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
//SOME JSON PARSING HAPPENS HERE
collectionView.delegate = self
collectionView.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let colcel = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! MyCollectionViewCell
colcel.contentView.layer.cornerRadius = 5.0
colcel.layer.shadowColor = UIColor.darkGray.cgColor
colcel.layer.shadowOffset = CGSize(width: 12, height: 4.0)
colcel.layer.shadowRadius = 12.0
colcel.layer.masksToBounds = false
return colcel
}
}
现在,当我尝试使用示例时:
colcel.topLabel.text = "someText"
我明白了:
致命错误:在展开Optional值时意外发现nil
当我删除viewDidLoad()
中的collectionview.register
,它可以正常工作。 现在的问题是我的register
行动不是必要的,还是错的?
//编辑。
我的细胞重新排序:
在viewDidLoad()
是这样的:
//Long Pressure for reordering
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.handleLongGesture))
self.collectionView.addGestureRecognizer(longPressGesture)
这是相应的功能:
func handleLongGesture(gesture: UILongPressGestureRecognizer) {
switch(gesture.state) {
case UIGestureRecognizerState.began:
guard let selectedIndexPath = self.collectionView.indexPathForItem(at: gesture.location(in: self.collectionView)) else {
break
}
collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
case UIGestureRecognizerState.changed:
collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view!))
case UIGestureRecognizerState.ended:
collectionView.endInteractiveMovement()
default:
collectionView.cancelInteractiveMovement()
}
}
我有这个功能:
func collectionView(_ collectionView: UICollectionView,
moveItemAt sourceIndexPath: IndexPath,
to destinationIndexPath: IndexPath)
{
// Update data model to reflect the change
let temp = devArray[sourceIndexPath.row]
devArray[sourceIndexPath.row] = devArray[destinationIndexPath.row]
devArray[destinationIndexPath.row] = temp
}
我跑的时候
self.collectionView.reloadData()
有时候位置跳跃
如果您使用具有相应基类的原型单元设计了故事板,则不应该register
该类。 故事板原型单元为您完成所有这些。
您手动注册类的唯一时间是以编程方式创建单元格。 在这种情况下,您应该删除原型单元格,但您的自定义类必须自己创建子视图并以编程方式连接出口(不再是@IBOutlet
引用)。
就您使用原型单元格而不是以编程方式创建单元格的原因而言,使用原型单元格要容易得多。 你必须编写更少的代码。 如果您使用单元格原型,故事板可以非常优雅地完成所有这些操作,因此我认为在上学和注册课程并以编程方式手动创建单元格没有任何好处。 这就是我们在制作原型单元之前的习惯。 但是使用storyboard与以编程方式创建的单元格不应该影响单元重用逻辑。
你说:
...在特殊情况下,细胞似乎没有被正确使用。
您应该告诉我们在什么情况下不重复使用单元格。 值得注意的是,当滚动速度非常快时,单元格在滚出视图后不会立即重复使用。 在重复使用之前有一点滞后。 如果那是你看到那种行为的情景,那么,是的,我对这种行为并不感到惊讶。 如果您没有看到它未成功出列/重复使用单元格,则分享有关您何时何地看到此行为的详细信息。
关于单独的重新排序问题, collectionView(_:moveItemAt:to:)
正在交换源和目标。 但你想要的是remove
和insert
:
override func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
let value = devArray.remove(at: sourceIndexPath.item)
devArray.insert(value, at: destinationIndexPath.item)
}
因为你正在交换,所以一个单元格看起来很好(所以当你完成拖动时一切看起来都很好),但中间的所有其他单元格都是错误的。 在重新加载集合视图和/或滚动然后返回之前,您不会看到它。 相反,通过remove
和insert
,模型应该保持同步。
请检查UICollectionViewCell属性上的Custom Class,确保值为MyCollectionViewCell - > ScreenShot
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.