我做了一些研究,但是我找不到任何关于如何在UICollectionView中水平居中单元格的代码示例.
而不是第一个单元格像这个X00,我希望它像这个0X0.有没有办法实现这个目标?
编辑:
想象我想要的东西:
当CollectionView中只有一个元素时,我需要它看起来像版本B. 当我有多个元素时,它应该像版本A但有更多元素.
当我只有1个元素时,它看起来像版本A,我想知道我怎么能让它看起来像B.
谢谢您的帮助!
Dar*_*el. 199
使用库不是一个好主意,如果你的目的只是这个,即中心对齐.
更好的是,您可以在collectionViewLayout函数中执行此简单计算.
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
let totalCellWidth = CellWidth * CellCount
let totalSpacingWidth = CellSpacing * (CellCount - 1)
let leftInset = (collectionViewWidth - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
let rightInset = leftInset
return UIEdgeInsets(top: 0, left: leftInset, bottom: 0, right: rightInset)
}
Run Code Online (Sandbox Code Playgroud)
Ahm*_*adi 46
Swift 4.2
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let totalCellWidth = 80 * collectionView.numberOfItems(inSection: 0)
let totalSpacingWidth = 10 * (collectionView.numberOfItems(inSection: 0) - 1)
let leftInset = (collectionView.layer.frame.size.width - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
let rightInset = leftInset
return UIEdgeInsets(top: 0, left: leftInset, bottom: 0, right: rightInset)
}
Run Code Online (Sandbox Code Playgroud)
斯威夫特3
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
let totalCellWidth = 80 * collectionView.numberOfItems(inSection: 0)
let totalSpacingWidth = 10 * (collectionView.numberOfItems(inSection: 0) - 1)
let leftInset = (collectionView.layer.frame.size.width - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
let rightInset = leftInset
return UIEdgeInsetsMake(0, leftInset, 0, rightInset)
}
Run Code Online (Sandbox Code Playgroud)
不要忘记添加协议
UICollectionViewDelegateFlowLayout
Run Code Online (Sandbox Code Playgroud)
osc*_*lon 22
试试这个Swift 4吧
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let cellWidth : CGFloat = 165.0
let numberOfCells = floor(self.view.frame.size.width / cellWidth)
let edgeInsets = (self.view.frame.size.width - (numberOfCells * cellWidth)) / (numberOfCells + 1)
return UIEdgeInsetsMake(15, edgeInsets, 0, edgeInsets)
}
Run Code Online (Sandbox Code Playgroud)
添加您的cellWidth而不是165.0
Two*_*aws 19
我使用KTCenterFlowLayout来做这件事,效果很好.它是一个自定义子类,UICollectionViewFlowLayout可以根据需要使单元格居中.(注意:通过发布一些代码来解决这个问题并非易事,这就是为什么我要链接到GitHub项目!)
Stu*_*ner 13
Darshan Patel的客观C版答案:
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
CGFloat totalCellWidth = kItemWidth * self.dataArray.count;
CGFloat totalSpacingWidth = kSpacing * (((float)self.dataArray.count - 1) < 0 ? 0 :self.dataArray.count - 1);
CGFloat leftInset = (self.bounds.size.width - (totalCellWidth + totalSpacingWidth)) / 2;
CGFloat rightInset = leftInset;
UIEdgeInsets sectionInset = UIEdgeInsetsMake(0, leftInset, 0, rightInset);
return sectionInset;
}
Run Code Online (Sandbox Code Playgroud)
流程布局的通用解决方案,如果页面小于宽度,则将页面居中;如果页面更多,则向左对齐
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
// Centering if there are fever pages
CGSize itemSize = [(UICollectionViewFlowLayout *)collectionViewLayout itemSize];
CGFloat spacing = [(UICollectionViewFlowLayout *)collectionViewLayout minimumLineSpacing];
NSInteger count = [self collectionView:self numberOfItemsInSection:section];
CGFloat totalCellWidth = itemSize.width * count;
CGFloat totalSpacingWidth = spacing * ((count - 1) < 0 ? 0 : count - 1);
CGFloat leftInset = (self.bounds.size.width - (totalCellWidth + totalSpacingWidth)) / 2;
if (leftInset < 0) {
UIEdgeInsets inset = [(UICollectionViewFlowLayout *)collectionViewLayout sectionInset];
return inset;
}
CGFloat rightInset = leftInset;
UIEdgeInsets sectionInset = UIEdgeInsetsMake(0, leftInset, 0, rightInset);
return sectionInset;
}
Run Code Online (Sandbox Code Playgroud)
Swift 版本(从 ObjC 转换而来)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
// Centering if there are fever pages
let itemSize: CGSize? = (collectionViewLayout as? UICollectionViewFlowLayout)?.itemSize
let spacing: CGFloat? = (collectionViewLayout as? UICollectionViewFlowLayout)?.minimumLineSpacing
let count: Int = self.collectionView(self, numberOfItemsInSection: section)
let totalCellWidth = (itemSize?.width ?? 0.0) * CGFloat(count)
let totalSpacingWidth = (spacing ?? 0.0) * CGFloat(((count - 1) < 0 ? 0 : count - 1))
let leftInset: CGFloat = (bounds.size.width - (totalCellWidth + totalSpacingWidth)) / 2
if leftInset < 0 {
let inset: UIEdgeInsets? = (collectionViewLayout as? UICollectionViewFlowLayout)?.sectionInset
return inset!
}
let rightInset: CGFloat = leftInset
let sectionInset = UIEdgeInsets(top: 0, left: Float(leftInset), bottom: 0, right: Float(rightInset))
return sectionInset
}
Run Code Online (Sandbox Code Playgroud)
您可以使用此扩展程序 (Swift 4)。
如果您collectionView有layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize.
它适用于任何细胞大小,并且在以下情况下完美运行 scrollDirection = .horizontal
public extension UICollectionView {
func centerContentHorizontalyByInsetIfNeeded(minimumInset: UIEdgeInsets) {
guard let layout = collectionViewLayout as? UICollectionViewFlowLayout,
layout.scrollDirection == .horizontal else {
assertionFailure("\(#function): layout.scrollDirection != .horizontal")
return
}
if layout.collectionViewContentSize.width > frame.size.width {
contentInset = minimumInset
} else {
contentInset = UIEdgeInsets(top: minimumInset.top,
left: (frame.size.width - layout.collectionViewContentSize.width) / 2,
bottom: minimumInset.bottom,
right: 0)
}
}
}
final class Foo: UIViewController {
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.centerContentHorizontalyByInsetIfNeeded(minimumInset: yourDefaultInset)
}
}
Run Code Online (Sandbox Code Playgroud)
希望对你有帮助!
略微修改@Safad Funy的答案,这对于Swift和iOS的最新版本对我来说是有用的。在这种情况下,我希望单元格的宽度为集合视图大小的三分之一。
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let totalCellWidth = Int(collectionView.layer.frame.size.width) / 3 * collectionView.numberOfItems(inSection: 0)
let totalSpacingWidth = (collectionView.numberOfItems(inSection: 0) - 1)
let leftInset = (collectionView.layer.frame.size.width - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
let rightInset = leftInset
return UIEdgeInsetsMake(0, leftInset, 0, rightInset)
}
Run Code Online (Sandbox Code Playgroud)
小智 5
Swift 4.2(水平和垂直)。这是粉红豹代码的小升级,非常感谢他!
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
let cellWidth: CGFloat = flowLayout.itemSize.width
let cellHieght: CGFloat = flowLayout.itemSize.height
let cellSpacing: CGFloat = flowLayout.minimumInteritemSpacing
let cellCount = CGFloat(collectionView.numberOfItems(inSection: section))
var collectionWidth = collectionView.frame.size.width
var collectionHeight = collectionView.frame.size.height
if #available(iOS 11.0, *) {
collectionWidth -= collectionView.safeAreaInsets.left + collectionView.safeAreaInsets.right
collectionHeight -= collectionView.safeAreaInsets.top + collectionView.safeAreaInsets.bottom
}
let totalWidth = cellWidth * cellCount + cellSpacing * (cellCount - 1)
let totalHieght = cellHieght * cellCount + cellSpacing * (cellCount - 1)
if totalWidth <= collectionWidth {
let edgeInsetWidth = (collectionWidth - totalWidth) / 2
print(edgeInsetWidth, edgeInsetWidth)
return UIEdgeInsets(top: 5, left: edgeInsetWidth, bottom: flowLayout.sectionInset.top, right: edgeInsetWidth)
} else {
let edgeInsetHieght = (collectionHeight - totalHieght) / 2
print(edgeInsetHieght, edgeInsetHieght)
return UIEdgeInsets(top: edgeInsetHieght, left: flowLayout.sectionInset.top, bottom: edgeInsetHieght, right: flowLayout.sectionInset.top)
}
}
Run Code Online (Sandbox Code Playgroud)
确保您的类符合UICollectionViewDelegateFlowLayout协议
这是Swift 5的较新版本,当单元格多于一行时,它也能正常工作:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
let cellWidth: CGFloat = flowLayout.itemSize.width
let cellSpacing: CGFloat = flowLayout.minimumInteritemSpacing
var cellCount = CGFloat(collectionView.numberOfItems(inSection: section))
var collectionWidth = collectionView.frame.size.width
var totalWidth: CGFloat
if #available(iOS 11.0, *) {
collectionWidth -= collectionView.safeAreaInsets.left + collectionView.safeAreaInsets.right
}
repeat {
totalWidth = cellWidth * cellCount + cellSpacing * (cellCount - 1)
cellCount -= 1
} while totalWidth >= collectionWidth
if (totalWidth > 0) {
let edgeInset = (collectionWidth - totalWidth) / 2
return UIEdgeInsets.init(top: flowLayout.sectionInset.top, left: edgeInset, bottom: flowLayout.sectionInset.bottom, right: edgeInset)
} else {
return flowLayout.sectionInset
}
}
Run Code Online (Sandbox Code Playgroud)
请确保你的类符合到UICollectionViewDelegateFlowLayout协议。
| 归档时间: |
|
| 查看次数: |
68754 次 |
| 最近记录: |