当使用自定义布局时,sizeForItemAt方法不会调用

我为我的集合视图使用自定义布局,但如果我使用自定义布局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 } }