Ios 滚动到CollectionView底部时,集合视图单元格无意中调整了大小

Ios 滚动到CollectionView底部时,集合视图单元格无意中调整了大小,ios,swift,uicollectionview,uikit,uicollectionviewdelegateflowlayout,Ios,Swift,Uicollectionview,Uikit,Uicollectionviewdelegateflowlayout,我正在建立一个图像集合视图(图库) 布局为每行3个单元格 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let width: CGFloat = (view.frame.width / 3) - 8

我正在建立一个图像集合视图(图库)

布局为每行3个单元格

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let width: CGFloat = (view.frame.width / 3) - 8
        let height: CGFloat = width

        return CGSize(width: width, height: height)
    }
在我滚动到“收藏”视图的底部之前,一切看起来都很棒

它来自:

致:

我还收到以下错误消息:

The behavior of the UICollectionViewFlowLayout is not defined because:

the item width must be less than the width of the UICollectionView minus the section insets left and right values, minus the content insets left and right values. 

Please check the values returned by the delegate.

The relevant UICollectionViewFlowLayout instance is <UICollectionViewFlowLayout: 0x7fa97f708c70>, and it is attached to <UICollectionView: 0x7fa981022000; frame = (0 0; 414 896); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x6000019986f0>; layer = <CALayer: 0x6000017a8820>; contentOffset: {0, 498.33333333333331}; contentSize: {414, 1250}; adjustedContentInset: {88, 0, 34, 0}; layout: <UICollectionViewFlowLayout: 0x7fa97f708c70>; dataSource: <MarsRover.GalleryCollectionVC: 0x7fa97f50b610>>.

未定义UICollectionViewFlowLayout的行为,因为: 项目宽度必须小于UICollectionView的宽度减去部分插入的左侧和右侧值,再减去内容插入的左侧和右侧值。 请检查委托返回的值。 相关的UICollectionViewFlowLayout实例为,并已附加到。
任何洞察都很好,我想把它也变成无限滚动(api预取),仅供参考,如果这意味着我可以忽略它。

由于您所有的项目都是相同大小的,所以不应该在委托方法中设置它们。相反,在viewDidLayoutSubviews中的flowLayout上设置一个静态大小(您可以从情节提要中拖动一个出口),并使用布局插图来执行此操作,这样您就不会出现数学错误:

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        let remainingSpace = collectionView.bounds.width
                            - flowLayout.sectionInset.left
                            - flowLayout.sectionInset.right
                            - flowLayout.minimumInteritemSpacing * (Constant.numberOfItemsAcross - 1)
        let dimension = remainingSpace / Constant.numberOfItemsAcross
        flowLayout.itemSize = CGSize(width: dimension, height: dimension)
    }

您得到的错误是指向项的宽度,因为问题是,项的宽度和间距基本上不能大于集合视图的宽度。这是因为集合视图具有垂直滚动

因此,为了实现集合视图的正确行为,必须将控制器设置为集合视图的
委托
,并采用
UICollectionViewDelegateFlowLayout
。在您的例子中,我可以看到您已经实现了
collectionView(uzy:,layout:,sizeForItemAt:
方法

在您的实现中,有一个明确的意图是将collectionView的宽度划分为三个相等的部分。计算考虑的是
self.view.width
减去8的第三部分。如果我假设正确,您打算留下8的项间间距。如果是这种情况,您应该将其指定为另一种方法:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 8
}
将项目间间距指定为8点

继续计算单元格的
宽度
高度
,然后必须将
collectionView.frame.width
除以,但在此之前必须从该数量中减去间距值,因为这是单元格的剩余空间

因此,您的实现将是

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    // We subtract 16 because there are 2 inter item spaces like:
    // [CELL] [spacing:8] [CELL] [spacing:8] [CELL]
    let usableWidth = collectionView.frame.width - (2 * 8) 

    let cellWidth: CGFloat = usableWidth / 3
    let cellHeight: CGFloat = cellWidth

    return CGSize(width: cellWidth, height: cellHeight)
}

这应该可以为您完成布局。

首先,为什么不使用边界而不是框架

其次,发生这种情况的原因很可能是因为在collectionView加载单元格时,您正在调整其他位置的布局(滚动将使其成为加载单元格)


您是否使用UIScrollViewDelegate方法对布局执行任何操作?

您是否尝试将集合视图项宽度计算更改为基于
collectionView
而不是
view.frame.width
?类似于:
让宽度:CGFloat=(collectionView.frame.width/3)-8
。谢谢,奥兰多,但我试过view.bounds.width、view.frame.width、view.frame.size.width、cv.frame.size.width、cv.frame.width等。。。