0

我正在构建图像的集合视图(图库)。

布局为每行 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)
    }

在我滚动到集合视图的底部之前,一切看起来都很棒。

它来自: 每行 3 个,看起来不错

to: 超级放大的图片,比屏幕还大

我也收到此错误消息:

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>>.

任何见解都会很棒,我也想把它变成无限滚动(api预取),如果这意味着我可以忽略它,仅供参考。

4

3 回答 3

1

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

因此,要为您的集合视图实现正确的行为,您必须将您的控制器设置delegate为集合视图并采用UICollectionViewDelegateFlowLayout. 在您的情况下,我可以看到您已经实现了该collectionView(_:, layout:, sizeForItemAt:方法。

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

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 8
}

这会将项目间的间距指定为 8 个点。

继续单元格的widthheight,然后您必须除以 ,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)
}

这应该为你做布局。

于 2019-11-07T22:46:37.787 回答
0

首先,为什么不使用bounds而不是frame

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

您是否使用 UIScrollViewDelegate 方法对布局做任何事情?

于 2019-11-08T00:09:49.953 回答
0

由于您所有的项目都是相同的大小,您不应该在委托方法中设置它们。而是在 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)
    }
于 2019-11-07T22:13:42.030 回答