我为UICollectionView
添加了UIViewController
,并为其制作了自定义单元格。
我使用sizeForItemAtIndexPath
方法设置单元格的大小,并在高度和宽度上将每个单元格设置为UIScreen.mainScreen().bounds.width/2
。基本上,每个单元格都是屏幕宽度的一半,高度相同。
然后我在单元格内部有一个UIImageView
,每条边都固定在单元格的相对边缘,这样图像视图就会填充单元格。我还有一个UILabel
,它在单元格中垂直和水平居中。
然而,在第一次加载时,单元格的大小正确,但内容在左上角的小方块中要小得多。 (如下图所示,我将单元格的contentView背景颜色设置为绿色,将imageView背景颜色设置为红色)。
然后向下滚动一点(我假设一个可重复使用的单元格出列)所有单元格都很好(滚动后再保持正常)。
导致内容在首次加载时没有被正确约束的原因是什么?
更新
我UIViewController
的部分代码:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell = collectionView.dequeueReusableCellWithReuseIdentifier("PrevDrawCell", forIndexPath: indexPath) as? PrevDrawCell
if cell == nil {
cell = PrevDrawCell()
}
cell!.drawVC = self
cell!.imageShortCode = self.tempImageURLs[indexPath.row]
// Pull image (async) and set after download
cell!.setupImage()
cell!.contentView.backgroundColor = UIColor.greenColor()
cell!.coverView.backgroundColor = UIColor.redColor()
cell!.dateLabel.font = UIFont(name: "HelveticaNeue-Light", size: 26)
cell!.dateLabel.text = "\(self.tempImageURLs.count-indexPath.row)/9"
return cell!
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
let size = UIScreen.mainScreen().bounds.width/2
return CGSize(width: size, height: size)
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
return UIEdgeInsetsZero
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
return 0
}
答案 0 :(得分:50)
看起来它仍然保留了contentView的100x100px基本大小,而单元格本身已经获得了正确的大小。您可以强制布局重置在返回单元格之前添加以下行:
cell?.layoutIfNeeded()
答案 1 :(得分:3)
我曾经遇到过类似的问题(即使正确的自动布局,我的细胞内容也不适合细胞)。该错误是由于没有打电话造成的
super.layoutSubviews()
覆盖了Cell类中的函数layoutSubviews()。
答案 2 :(得分:2)
就我而言,我需要将单元格的高度分配为 collectionView 的高度。但是集合视图的高度取决于屏幕的大小。 所以里面 sizeForItemAt 委托
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: currentScreenWidth, height: collectionView.frame.height)
}
为了完成这项工作,我需要从 viewDidLayoutSubviews 调用 reloadData 函数
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
mycollection.reloadData()
}
答案 3 :(得分:1)
感谢vin047的精彩提示。
在我们的案例中,我发现问题在于超级呼叫顺序。
但具有整体表视图(或集合视图)。不在单元格中。
class UnusualCollectionView: UICollectionView {
override func layoutSubviews() {
super.layoutSubviews()
contentInset = UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 0)
}
class UnusualCollectionView: UICollectionView {
override func layoutSubviews() {
contentInset = UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 0)
super.layoutSubviews()
}
该问题导致了一些非常不稳定的行为。例如,第12个单元格(实际上不是)始终在垂直方向上移动了很长一段距离。永远是第12个牢房!谁知道?
vin047在这里度过了美好的一天,
答案 4 :(得分:0)
对于那些使用Storyboard + AutoLayout并选择在运行时处于活动状态的约束的人:
在使用dequeueReusableCell时,在第一次加载时,将创建该单元格,但尚未初始化其视图,因此不会保存约束更改-使用在Storyboard中设置的任何内容。对我来说,解决方案是在视图加载后更新约束:
override func layoutSubviews() {
super.layoutSubviews()
adjustIconWidths()
}
答案 5 :(得分:0)
答案 6 :(得分:0)
我遇到了类似的问题,不完全相同,但可以帮助某人。
我没有在单元格中调用 super.prepareForReuse()
进行了覆盖 prepareForReuse。因此,当我将 UICollectionViewCompositionalLayout 与 .estimated(100) 用于单元格高度时,我在设备旋转时出现了奇怪的行为:如果在不滚动的情况下旋转,则在视图出现后立即滚动 - 您将获得具有估计高度 (100) 的单元格,而不是更新了布局。
所以,试着检查这部分:
override func prepareForReuse() {
super.prepareForReuse()
}
答案 7 :(得分:0)
嘿伙计们,如果仍然有人因为自动调整单元格而无法设置内容大小,您可以将其添加到您的集合视图中,您可以获得内容大小
*此处滚动使视图获得正确的内容大小,因此使您的 CollectionView 可滚动或禁用它,在这两种情况下,您都将在单元格中加载数据后获得内容大小
`XCollectionView.isScrollEnabled = true/false`
*然后从数据源重新加载数据
`XCollectionView.reloadData()`
*然后调用 layoutneeded
`XCollectionView.layoutIfNedded()`
*然后您可以检查,内容大小将等于您的内容
`XCollectionView.collectionViewLayout.collectionViewContentSize.height`
*现在将集合视图的高度设置为内容高度,您就可以开始了