如何居中alignmentSwift3.0 UICollectionView的单元格?

描述:

Objective-CSwift2.0 : 如何居中alignmentUICollectionView的单元格?

我通常会尝试将Swift2.0答案转换为Swift3.0解决scheme,但是方法如下:

 func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets { let edgeInsets = (screenWight - (CGFloat(elements.count) * 50) - (CGFloat(elements.count) * 10)) / 2 return UIEdgeInsetsMake(0, edgeInsets, 0, 0); } 

似乎并不存在于Swift3.0 ,唯一的其他方法,我觉得有用的是:

 func collectionView(_ collectionView: UICollectionView, transitionLayoutForOldLayout fromLayout: UICollectionViewLayout, newLayout toLayout: UICollectionViewLayout) -> UICollectionViewTransitionLayout { <#code#> } 

但我不确定如何正确实施它。

题:

如何居中alignmentUICollectionView Swift3.0的单元格?

(iOS和tvOS的一个简单而通用的解决scheme将是完美的)

虽然rottenoats的答案很好,但它有一个额外的间距错误,并没有使用很多可用的swift 3语法。 我已经解决了这个问题,并减less了依赖到局部variables的数量。

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { // Make sure that the number of items is worth the computing effort. guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout, let dataSourceCount = collectionView.dataSource?.collectionView(collectionView, numberOfItemsInSection: section), dataSourceCount > 0 else { return .zero } let cellCount = CGFloat(dataSourceCount) let itemSpacing = flowLayout.minimumInteritemSpacing let cellWidth = flowLayout.itemSize.width + itemSpacing var insets = flowLayout.sectionInset // Make sure to remove the last item spacing or it will // miscalculate the actual total width. let totalCellWidth = (cellWidth * cellCount) - itemSpacing let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right // If the number of cells that exist take up less room than the // collection view width, then center the content with the appropriate insets. // Otherwise return the default layout inset. guard totalCellWidth < contentWidth else { return insets } // Calculate the right amount of padding to center the cells. let padding = (contentWidth - totalCellWidth) / 2.0 insets.left = padding insets.right = padding return insets } 

NB:这个片段只能用于水平滚动,但可以很容易地进行调整。

这最终成为我使用的解决scheme。 阅读代码评论以获得更好的理解。 Swift 3.0

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { //Where elements_count is the count of all your items in that //Collection view... let cellCount = CGFloat(elements_count) //If the cell count is zero, there is no point in calculating anything. if cellCount > 0 { let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout let cellWidth = flowLayout.itemSize.width + flowLayout.minimumInteritemSpacing //20.00 was just extra spacing I wanted to add to my cell. let totalCellWidth = cellWidth*cellCount + 20.00 * (cellCount-1) let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right if (totalCellWidth < contentWidth) { //If the number of cells that exists take up less room than the //collection view width... then there is an actual point to centering them. //Calculate the right amount of padding to center the cells. let padding = (contentWidth - totalCellWidth) / 2.0 return UIEdgeInsetsMake(0, padding, 0, padding) } else { //Pretty much if the number of cells that exist take up //more room than the actual collectionView width, there is no // point in trying to center them. So we leave the default behavior. return UIEdgeInsetsMake(0, 40, 0, 40) } } return UIEdgeInsets.zero } 

你正在寻找的方法在Swift 3有一个不同的签名。 新签名是这样的:

 optional public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets 

PS:这个方法存在于UICollectionViewDelegateFlowLayout协议中。
希望这会有所帮助。

假设你符合UICollectionViewDelegateFlowLayout ,它应该是:

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { let edgeInsets = (screenWight - (CGFloat(elements.count) * 50) - (CGFloat(elements.count) * 10)) / 2 return UIEdgeInsets(top: 0, left: edgeInsets, bottom: 0, right: 0) } 

轻微的@rottenoats回答。 这是更通用的。

最重要的是记住要使你的视图控制器符合UICollectionViewDelegateFlowLayout协议。

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout else { return .zero } let cellCount = CGFloat(collectionView.numberOfItems(inSection: section)) if cellCount > 0 { let cellWidth = flowLayout.itemSize.width + flowLayout.minimumInteritemSpacing let totalCellWidth = cellWidth * cellCount let contentWidth = collectionView.frame.size.width - collectionView.contentInset.left - collectionView.contentInset.right - flowLayout.headerReferenceSize.width - flowLayout.footerReferenceSize.width if (totalCellWidth < contentWidth) { let padding = (contentWidth - totalCellWidth + flowLayout.minimumInteritemSpacing) / 2.0 return UIEdgeInsetsMake(0, padding, 0, 0) } } return .zero } 
 func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets { let allCellWidth = KcellWidth * numberOfCell let cellSpacingWidth = CellSpacing * (numberOfCell - 1) let leftInset = (collectionViewWidth - CGFloat(allCellWidth + cellSpacingWidth)) / 2 let rightInset = leftInset return UIEdgeInsetsMake(0, leftInset, 0, rightInset) } 

而不是每次在您的委托方法中添加此代码,您可以添加自定义stream布局类到您的collectionView。 linkToSuchLayout