在 Swift 4 中调用 collectionView(_ :layout:sizeForItemAt:)

Call collectionView(_ :layout:sizeForItemAt:) in Swift 4

我使用 UICollectionView 制作了图库。

如果降低屏幕,图像应该会继续出现并停在 20。

代码不断更新。 但是设置cell大小的函数collectionView(_:layout:sizeForItemAt:)没有起作用。 所以连续显示的只有20张图片

在 viewDidLoad() 上

if let layoutt = artCollectionView?.collectionViewLayout as? PinterestLayout
{
    layoutt.delegate = self
}

单元格设置

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCollectionViewCell", for: indexPath) as? HomeCollectionViewCell,

    let arts = self.artList else { return HomeCollectionViewCell() }
    if arts.count > indexPath.row
    {
        let model = arts[indexPath.row]

        cell.imgView.sd_setImage(with: URLHelper.createEncodedURL(url: model.thumburl), completed: nil)
    }
    return cell
}

return 单元格大小

extension HomeViewController : PinterestLayoutDelegate
{
    func collectionView(_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath:IndexPath) -> CGFloat
    {
        return CGFloat(300.0)
    }
}

目前,该函数仅在应用启动时执行一次。你知道如何 运行 每次我想要的功能吗?

您需要实施 UICollectionViewDelegateFlowLayout。 您可以在此处阅读有关该协议的更多信息: UICollectionViewDelegateFlowLayout protocol

示例:

extension viewController: UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 50, height: 300)
    }
}

请按照下面 UICollectionView 中的步骤安装 PinterestLayout

PinterestLayout 设置为您的 collection 视图。

let layout = PinterestLayout()
collectionView.collectionViewLayout = layout

设置布局

layout.delegate = self
layout.cellPadding = 5
layout.numberOfColumns = 2

实现PinterestLayoutDelegate

的方法
extension CustomCollectionVC: PinterestLayoutDelegate {

    func collectionView(collectionView: UICollectionView,
                        heightForImageAtIndexPath indexPath: IndexPath,
                        withWidth: CGFloat) -> CGFloat {
        let image = images[indexPath.item]

        return image.height(forWidth: withWidth)
    }

    func collectionView(collectionView: UICollectionView,
                        heightForAnnotationAtIndexPath indexPath: IndexPath,
                        withWidth: CGFloat) -> CGFloat {
        let textFont = UIFont(name: "Arial-ItalicMT", size: 11)!                
        return "Some text".heightForWidth(width: withWidth, font: textFont)
    }
}

加载数据时使布局无效并在 collection 视图上重新加载数据。

collectionView.collectionViewLayout.invalidateLayout()
collectionView.reloadData()

观察:

func collectionView(_ collectionView: UICollectionView, heightForPhotoAtIndexPath indexPath:IndexPath) -> CGFloat

试试这个而不是上面的:

func collectionView(collectionView: UICollectionView,
                        heightForImageAtIndexPath indexPath: IndexPath,
                        withWidth: CGFloat) -> CGFloat

如果你查看 PinterestLayout class 的 prepare() 方法,你可以看到下面的代码

guard
    cache.isEmpty == true,
    let collectionView = collectionView
    else {
      return
}

当您重新加载 colectionView 时,缓存不再为空,因此它 returns 返回而不改变布局。

所以调用prepare的时候只需要删除缓存值即可。 在 guard

之前添加 removeAll()
cache.removeAll()