ios - 滚动到 CollectionView 底部时,Collection View Cell 会无意中调整大小

标签 ios swift uicollectionview uikit uicollectionviewdelegateflowlayout

我正在构建图像的 Collection View (图库)。

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

一切看起来都很棒,直到我滚动到 Collection View 的底部。

它来自: 3 per row, looks good

至: super blown up picture, larger than the screen

我也收到此错误消息:

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 预取),仅供引用,如果这意味着我可以忽略它。

最佳答案

您收到的错误指出项目的宽度是问题所在,也就是说,基本上项目的宽度和间距不能大于 Collection View 的宽度。这是因为您的 Collection View 具有垂直滚动。

因此,要为 Collection View 实现正确的行为,您必须将 Controller 设置为 Collection View 的委托(delegate),并采用UICollectionViewDelegateFlowLayout。在你的例子中,我可以看到你已经实现了collectionView(_:,layout:,sizeForItemAt:方法。

在您的实现中,有一个明确的意图是将 collectionView 的宽度分为三等份。该计算考虑了 self.view.width 的三分之一减去八。如果我假设正确的话,您打算将项目间间距保留为 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)
}

这应该为您完成布局。

关于ios - 滚动到 CollectionView 底部时,Collection View Cell 会无意中调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58756776/

相关文章:

iOS自定义状态栏背景颜色不显示

ios - 如何在 : IOS 9 View 外点击时关闭 iPad 上的弹出 View Controller

swift - 无法将类型 'MenuView' 的值分配给类型 'some View'

ios - 更新 UICollectionView 中不可见的单元格

ios - 如何在ios中创建没有tableview和collection view的行

ios - 在 iOS [Swift 3] 中将视频裁剪为正方形

ios - UISwipeGestureRecognizerDirection 仅识别正确的手势

ios - 将事件指示器设置为 CollectionViewCell

ios - NSDateFormatter 提前一天

ios - 如何在 swift(反射/镜像)中动态找到属性的类型?