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

时间:2015-10-04 12:51:23

标签: ios swift ipad uicollectionview

我有一个UICollectionView,它由popover演示文稿显示。 UICollectionView包含16行,每行10个单元格,我希望单元格填充UICollectionView的宽度。我正在尝试在viewWillTransitionToSize中调整每个单元格的大小,但是我无法获得正确的值。

如何获得UICollectionView的宽度,因为过渡后它将是

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

从70/30更改为50/50使我的细胞太小:

70/30 correct

50/50 incorrect

从50/50更改为70/30会让我的单元格过大:

50/50 correct

70/30 incorrect

当前代码:

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);


}

}

1 个答案:

答案 0 :(得分:3)

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

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

然后我可以删除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
     }

  }

}