UICollectionViewDelegateFlowLayout Edge Insets无法被sizeForItemAt函数识别?

时间:2017-04-02 07:16:10

标签: ios swift uicollectionview

正如标题所示,我似乎遇到了一个奇怪的问题。我在这里尝试做的就是创建一个2列的集合视图,而无需将任何内容硬编码到我的委托方法中。在调试时,我发现在sizeForItemAt之后调用insetForSectionAt,因此在计算每个单元格的大小时不会考虑自定义插入。

extension ViewController: UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let flowLayout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
    print("left: ", flowLayout.sectionInset.left)   // Prints out 0.0
    print("right: ", flowLayout.sectionInset.right) // Prints out 0.0
    let marginsAndInsets = flowLayout.sectionInset.left + flowLayout.sectionInset.right + flowLayout.minimumInteritemSpacing * (cellsPerRow - 1)
    let itemWidth = (collectionView.bounds.size.width - marginsAndInsets) / cellsPerRow
    return CGSize(width: itemWidth, height: itemWidth)
}

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

这个问题可以通过将值直接硬编码到itemWidth变量中来解决,因为我知道左右插图的值,10 + 10

let itemWidth = (collectionView.bounds.size.width - marginsAndInsets - 20) / cellsPerRow

但是,我必须相信有更好的方法,在完成UIEdgeInset计算后如何调用reloadData以便我的单元格大小合适?

1 个答案:

答案 0 :(得分:0)

所以这就是我最终做的,我只是在为collectionView及其单元格创建大小时直接添加了自定义。

class PinController: UICollectionViewController {

fileprivate let pinCellId = "pinCellId"
fileprivate let cellsPerRow: CGFloat = 2.0
fileprivate let margin: CGFloat = 10.0
fileprivate let topMargin: CGFloat = 2.0
}


extension PinController: UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let flowLayout = customize(collectionViewLayout, margin: margin)
    let itemWidth = cellWidth(collectionView, layout: flowLayout, cellsPerRow: cellsPerRow)
    return CGSize(width: itemWidth, height: itemWidth * 1.1)
}

/*
 Customizes the layout of a collectionView with space to the left and right of each cell that is 
 specified with the parameter margin
*/
private func customize(_ collectionViewLayout: UICollectionViewLayout, margin: CGFloat) -> UICollectionViewFlowLayout {
    let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
    // Interitem spacing affects the horrizontal spacing between cells
    flowLayout.minimumInteritemSpacing = margin
    // Line spacing affects the vertical space between cells
    flowLayout.minimumLineSpacing = margin
    // Section insets affect the entire container for the collectionView cells
    flowLayout.sectionInset = UIEdgeInsets(top: topMargin, left: margin, bottom: 0, right: margin)
    return flowLayout
}

/*
 Calculates the proper size of an individual cell with the specified number of cells in a row desired,
 along with the layout of the collectionView
 */
private func cellWidth(_ collectionView: UICollectionView, layout flowLayout: UICollectionViewFlowLayout, cellsPerRow: CGFloat) -> CGFloat {
    // Calculate the ammount of "horizontal space" that will be needed in a row
    let marginsAndInsets = flowLayout.sectionInset.left + flowLayout.sectionInset.right + flowLayout.minimumInteritemSpacing * (cellsPerRow - 1)
    let itemWidth = (collectionView.bounds.size.width - marginsAndInsets) / cellsPerRow
    return itemWidth
}
}