首次加载

时间:2015-09-15 18:28:16

标签: ios objective-c swift uicollectionview uicollectionviewcell

我为UICollectionView添加了UIViewController,并为其制作了自定义单元格。

我使用sizeForItemAtIndexPath方法设置单元格的大小,并在高度和宽度上将每个单元格设置为UIScreen.mainScreen().bounds.width/2。基本上,每个单元格都是屏幕宽度的一半,高度相同。

然后我在单元格内部有一个UIImageView,每条边都固定在单元格的相对边缘,这样图像视图就会填充单元格。我还有一个UILabel,它在单元格中垂直和水平居中。

然而,在第一次加载时,单元格的大小正确,但内容在左上角的小方块中要小得多。 (如下图所示,我将单元格的contentView背景颜色设置为绿色,将imageView背景颜色设置为红色)。

enter image description here

然后向下滚动一点(我假设一个可重复使用的单元格出列)所有单元格都很好(滚动后再保持正常)。

enter image description here

导致内容在首次加载时没有被正确约束的原因是什么?

更新

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
}

8 个答案:

答案 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)

对我有用的是将“集合视图”上的Estimate Size从“自动”更改为“无”。

collection view estimate size

答案 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`

*现在将集合视图的高度设置为内容高度,您就可以开始了