【问题标题】:Calling invalidateLayout() or reloadData() to reload a UICollectionView created from storyboard after device rotation调用 invalidateLayout() 或 reloadData() 以在设备旋转后重新加载从情节提要创建的 UICollectionView
【发布时间】:2019-09-09 15:26:09
【问题描述】:

UITableViewControllerUITableViewCell 中,我有一个网格,每行有固定数量的静态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 没有invalidLayout(),因为UICollectionView 是在IB 中创建的(据我所知),那么如何在我的UICollectionView 上调用invalidateLayout?

【问题讨论】:

  • CollectionView为什么不用invalidLayout()?同时更改设备方向
  • 您是否可以从UITableViewCell 访问UICollectionView?如果是,请覆盖UITableViewCell 中的layoutSubviews 并在UICollectionView 上调用invalidateLayout
  • @surToTheW - 在情节提要中创建静态单元格,我不确定如何实例化或访问 UITableViewCell? @ Nikunj - 你能链接到完整的细节吗?会试试的。
  • 我错过了关于静态单元格的部分。您可以在 TableViewController 中为它们提供插座。或者更好的出口系列。它们有多少个细胞?然后你可以覆盖viewWillTransitionToSize:withTransitionCoordinator:viewWillLayoutSubviews 并在那里调用invalidateLayout。
  • @surToTheW - 是的,确实,这非常完美。谢谢你。我在 IB 中建立连接时遇到了麻烦(它不会通过 ctrl-drag 和 drop 来实现),但是根据您的说明,我将其编码并反向连接,现在它可以工作了。再次感谢。

标签: ios swift xcode uicollectionview storyboard


【解决方案1】:

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

首先,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()
}

【讨论】:

    猜你喜欢
    • 2018-01-05
    • 2012-11-23
    • 2017-05-29
    • 2014-03-20
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多