如何在 viewWillTransitionToSize 之后获取子视图的大小

How to get the subview's size after viewWillTransitionToSize

我有一个 UICollectionView,它通过弹出窗口显示。 UICollectionView 包含 16 行,每行 10 个单元格,我希望这些单元格填满 UICollectionView 的宽度。我正在尝试调整 viewWillTransitionToSize 中每个单元格的大小,但我无法获得正确的值。

如何获得 UICollectionView 的宽度,因为它在过渡 之后会是这样?

在 iPad Air 2 上切换 50/50 和 70/30 分屏时出现问题。

从 70/30 更改为 50/50 使我的单元格太小:

从 50/50 更改为 70/30 使我的单元格太大:

当前代码:

class ColorPickerCollectionViewController: UICollectionViewController {


var cellsize:CGSize?;


override func viewDidLoad() {
    super.viewDidLoad()

    // Register cell classes
    self.collectionView!.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)

    // Do any additional setup after loading the view.
    if let flowLayout = self.collectionViewLayout as? UICollectionViewFlowLayout {

        flowLayout.minimumInteritemSpacing = 0;
        flowLayout.minimumLineSpacing = 0;
        flowLayout.sectionInset = UIEdgeInsetsMake(0,0,0,0);

    }

}

// MARK: UICollectionViewDataSource

override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 16;
}


override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10;
}

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as UICollectionViewCell

    // Configure the cell

    let colorView = getColorViewForCell(indexPath, cell: cell);
    cell.contentView.addSubview(colorView);

    cell.selectedBackgroundView = UIView();
    cell.selectedBackgroundView!.backgroundColor = UIColor.whiteColor();

    return cell
}

func getColorViewForCell(indexPath:NSIndexPath, cell:UICollectionViewCell) -> UIView {
    let colorView = UIView();
    colorView.backgroundColor = UIColor.blueColor();
    colorView.frame = CGRectMake(cell.bounds.origin.x + 1, cell.bounds.origin.y + 1, cell.bounds.width - 2, cell.bounds.height - 2);
    colorView.translatesAutoresizingMaskIntoConstraints = false;
    return colorView;
}


func collectionView(collectionView: UICollectionView,
    layout collectionViewLayout: UICollectionViewLayout,
    sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

        if self.cellsize == nil {
            let width = CGFloat(collectionView.frame.width / 10);
            cellsize = CGSize(width: width, height: width);
        }

        return self.cellsize!;
}

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {

    NSLog("viewWillTransitionToSize")
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator);

    //What do I do here?
    self.cellsize //= ???;


    let cView:UICollectionView = self.collectionView!;
    cView.performBatchUpdates(nil, completion: nil);


}

}

新解决方案,感谢@MikePollard 关于子类化 UICollectionViewFlowLayout 的评论。

我创建了一个子类 ColorPickerFlowLayout,其完整内容如下。我将其设置为集合视图的布局,并让 func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize return 布局的单元格大小。

然后我可以在 UICollectionViewController 中删除 viewWillTransitionToSize

import UIKit

class ColorPickerFlowLayout: UICollectionViewFlowLayout {

  private var cellSize:CGSize? = nil
  var previousBounds: CGRect? = nil

  required init?(coder aDecoder: NSCoder) {
     super.init(coder: aDecoder)
  }

  func getCellSize() -> CGSize? {

     return cellSize
  }

  override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {

     if previousBounds == nil || previousBounds!.width != newBounds.width {

        let width = CGFloat(newBounds.width / 10)
        cellSize = CGSize(width: width, height: width)

        previousBounds = newBounds

        self.collectionView?.performBatchUpdates(nil, completion: nil)

        return true
     } else {

        return false
     }

  }

}