0

很长一段时间后,我正在重新制作 Swift 和 UIKit。

工作流程:

  1. 我创建了一个 ViewController,UICollectionView它的中心在 X 和 Y 轴上以及与根视图成比例的宽度和高度都对齐。
  2. 分配给collectionview.delegate 和collectionView.dataSource 它相应的类实例对应UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
  3. 我创建了一个 UICollectionViewCell 并在 cellforItemAt... 中调用 dequeuereusablecell...
  4. 我可以访问 sizeForItemAt... 来计算合适的大小
    // item count represents number of cells per row in a section within collectionview
    let refWidth = collectionView.frame.width / CGFloat(itemCount); // sectionInsets are UIEdgeInsets.zero for simplicity in reproducing the issue
    let calculatedSize = CGSize(width: refWidth, height: refWidth/2 )
    
  5. 在 ViewController 中实现traitCollectionDidChange并在 collectionView 上强制 reloadData
  6. 我一直在使用许多设备(确切地说是模拟器)进行测试,它适用于大多数情况

设想:

  1. 如果水平和垂直大小类完全相同 - 示例:iPad Mini
  2. 项目计数为 1
  3. 页面首先以横向打开
  4. 然后页面被旋转成纵向

问题:

  1. 集合不会重新加载,因为 traitcollection 没有改变。
  2. Cell的当前宽度大于CollectionView的当前宽度

我尝试过的几种方法:

  1. 在 cellForItemAt... 方法中,在返回单元格之前,我使用 CollectionView 向单元格添加了一个约束,如下所示 - `Applicatin Crashed 并显示无法应用此类约束的消息。
        let itemCount = itemsPerRowInEachSection(collectionView)
        if cell.contentView.constraints.first(where: { cst in cst.identifier == "widthConst" }) != nil {
            let newConst = NSLayoutConstraint(item: cell,
                                              attribute: .width,
                                              relatedBy: .equal,
                                              toItem: collectionView,
                                              attribute: .width,
                                              multiplier: CGFloat(1)/CGFloat(itemCount),
                                              constant: 0)
            newConst.identifier = "widthConst"
            cell.addConstraint(newConst)
        }
    
  2. 类似于第一种方法,但尝试在 interfacebuilder 中应用约束。没有办法做到这一点,因为在 CollectionView 和 CollectionViewCell 之间单击并拖动命令根本不会提示任何约束

问题:

  1. 我应该实现诸如方向更改侦听器之类的东西并在那里重新加载collectionView而不是特征集合更改侦听器吗?
    • 如果我选择定向侦听器,将来如果我继续工作,多任务支持,如果我改变 traitCollection 而不改变方向,这种方法不起作用。
    • 如果我同时实现 traitCollection 和 Orientation Change Listeners,很多时候它们会发生冲突并尝试重新加载 collectionView 两次。
  2. 有人可以帮我找到适合这个问题的解决方案吗?
4

1 回答 1

1

根据OP评论...

如果您需要根据视图的大小修改布局- 例如设备旋转 - 您可以使用:

func viewWillTransition(to size: CGSize, 
               with coordinator: UIViewControllerTransitionCoordinator)

来自 Apple 的文档

UIKit 在更改呈现的视图控制器视图的大小之前调用此方法。您可以在自己的对象中覆盖此方法,并使用它来执行与大小更改相关的其他任务。例如,容器视图控制器可能使用此方法来覆盖其嵌入式子视图控制器的特征。使用提供的协调器对象为您所做的任何更改设置动画。

于 2022-01-02T16:31:22.510 回答