首页 > 解决方案 > 调用 invalidateLayout() 或 reloadData() 以在设备旋转后重新加载从情节提要创建的 UICollectionView

问题描述

UITableViewController, 中UITableViewCell,我有一个网格,UICollectionViewCells每行具有固定数量的静态(无间距)。

extension NounsTVC: UICollectionViewDataSource {

    func collectionView( _ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return cellIds.count
    }

    func collectionView( _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell( withReuseIdentifier: cellIds[indexPath.item], for: indexPath)
        cell.layer.borderColor = UIColor.gray.cgColor
        cell.layer.borderWidth = 0.5
        return cell
    }
}

extension NounsTVC: UICollectionViewDelegateFlowLayout
{
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
    }

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

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

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let availableWidth = collectionView.bounds.size.width
        let minimumWidth = floor(availableWidth / cellsPerRow)
        let remainder = availableWidth - minimumWidth * CGFloat(cellsPerRow)

        let columnIndex = indexPath.row % Int(cellsPerRow)
        let cellWidth = CGFloat(columnIndex) < remainder ? minimumWidth + 1 : minimumWidth
        return CGSize(width: cellWidth, height: 45)
    }
}

工作正常。

但是,当我旋转设备时,它需要调用这些布局方法。

这看起来像答案:Swift: How to refresh UICollectionView layout after rotation of the device

但我没有我UICollectionView的 asinvalidLayout()因为它UICollectionView是在 IB 中创建的(据我所知),那么我如何在我的 IB 上调用 invalidateLayoutUICollectionView呢?

标签: iosswiftxcodeuicollectionviewstoryboard

解决方案


在上述情况中发现了两个问题。

首先,xcode 没有通过在情节提要和 .swift 文件之间拖动一条线来在我的自定义 UITableViewCell 中创建 IBOutlet(显然是某些星座中的错误)。解决方案是手动输入代码,然后按 ctrl 键将其反向拖放到情节提要中的正确视图。

@IBOutlet weak var myCollectionView: UICollectionView!

其次,因为集合视图是在自定义 UITableViewCell 中实例化的,所以无法使用 viewWillTransitionToSize:withTransitionCoordinator: 或 viewWillLayoutSubviews(表视图方法)。但是, UITableViewCell 确实具有以下内容,其中可以调用 .invalidateLayout() :

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
{
    super.traitCollectionDidChange(previousTraitCollection)
    guard previousTraitCollection != nil else
    { return }
    myCollectionView.collectionViewLayout.invalidateLayout()
}

推荐阅读