ios - uicollectionview教學 - uicollectionviewcontroller



當使用自定義佈局時,sizeForItemAt方法不會調用 (1)

我為我的集合視圖使用自定義佈局,但如果我使用自定義佈局sizeForItemAt方法不調用。

我的自定義佈局:

public class HorizontalCollectionViewLayout : UICollectionViewLayout {
    var itemSize = CGSize(width: 0, height: 0) {
        didSet {
            invalidateLayout()
        }
    }
    private var cellCount = 0
    private var boundsSize = CGSize(width: 0, height: 0)

    public override func prepare() {
        cellCount = self.collectionView!.numberOfItems(inSection: 0)
        boundsSize = self.collectionView!.bounds.size
    }
    public override var collectionViewContentSize: CGSize {
        let verticalItemsCount = Int(floor(boundsSize.height / itemSize.height))
        let horizontalItemsCount = Int(floor(boundsSize.width / itemSize.width))

        let itemsPerPage = verticalItemsCount * horizontalItemsCount
        let numberOfItems = cellCount
        let numberOfPages = Int(ceil(Double(numberOfItems) / Double(itemsPerPage)))

        var size = boundsSize
        size.width = CGFloat(numberOfPages) * boundsSize.width
        return size
    }

    public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        var allAttributes = [UICollectionViewLayoutAttributes]()
        if cellCount > 0 {
        for i in 0...(cellCount-1) {
            let indexPath = IndexPath(row: i, section: 0)
            let attr = self.computeLayoutAttributesForCellAt(indexPath: indexPath)
            allAttributes.append(attr)
        }
        }
        return allAttributes
    }

    public override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        return computeLayoutAttributesForCellAt(indexPath: indexPath)
    }

    public override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        return true
    }

    private func computeLayoutAttributesForCellAt(indexPath:IndexPath)
        -> UICollectionViewLayoutAttributes {
            let row = indexPath.row
            let bounds = self.collectionView!.bounds

            let verticalItemsCount = Int(floor(boundsSize.height / itemSize.height))
            let horizontalItemsCount = Int(floor(boundsSize.width / itemSize.width))
            let itemsPerPage = verticalItemsCount * horizontalItemsCount

            let columnPosition = row % horizontalItemsCount
            let rowPosition = (row/horizontalItemsCount)%verticalItemsCount
            let itemPage = Int(floor(Double(row)/Double(itemsPerPage)))

            let attr = UICollectionViewLayoutAttributes(forCellWith: indexPath)

            var frame = CGRect(x: 0,y: 0,width: 0,height: 0)
            frame.origin.x = CGFloat(itemPage) * bounds.size.width + CGFloat(columnPosition) * itemSize.width
            frame.origin.y = CGFloat(rowPosition) * itemSize.height
            frame.size = itemSize
            attr.frame = frame

            return attr
    }
}

我在viewDidLoad方法中設置這個佈局:

let itemWidth = 100
let itemHeight = 100
let horizontalCV = HorizontalCollectionViewLayout();
horizontalCV.itemSize = CGSize(width: itemWidth, height: itemHeight)

instagramCollection.collectionViewLayout = horizontalCV
self.instagramCollection.delegate=self
self.instagramCollection.dataSource=self

其他集合視圖方法正常工作,如numberOfItemsInSectioncellForItemAt等,但我不能為我的集合視圖設置插圖或單元格間距。

我試過下面的代碼, 下面的方法是不會調用的。

func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize.init(width: (instagramCollection.frame.width / 3.0), height: instagramCollection.frame.height / 2.0)
}


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

另外我試圖設置故事板的間隔和間距也不起作用。

我的集合視圖現在使用零填充所有的插入和間距。

如何解決這個問題?


你應該添加你的控制器佈局委託的實現。 (你添加了這些方法,但是他們沒有被調用)

所以,不僅UICollectionViewDelegate,UICollectionViewDataSource,還有UICollectionViewDelegateFlowLayout。

像擴展,例如。

extension YourController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView,
                    layout collectionViewLayout: UICollectionViewLayout,
                    sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize.init(width: (instagramCollection.frame.width / 3.0), height: instagramCollection.frame.height / 2.0)
}


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




uikit