【发布时间】:2012-12-07 21:37:33
【问题描述】:
我有一个显示照片的UICollectionView。我使用UICollectionViewFlowLayout 创建了collectionview。它工作得很好,但我想在边距上有间距。是否可以使用UICollectionViewFlowLayout 来做到这一点,还是我必须实现自己的UICollectionViewLayout?
【问题讨论】:
标签: ios uicollectionview uikit
我有一个显示照片的UICollectionView。我使用UICollectionViewFlowLayout 创建了collectionview。它工作得很好,但我想在边距上有间距。是否可以使用UICollectionViewFlowLayout 来做到这一点,还是我必须实现自己的UICollectionViewLayout?
【问题讨论】:
标签: ios uicollectionview uikit
虽然这个帖子已经包含了一堆有用的答案,但我想根据 William Hu 的回答添加一个现代 Swift 版本。它还改进了两件事:
代码如下:
// Create flow layout
let flow = UICollectionViewFlowLayout()
// Define layout constants
let itemSpacing: CGFloat = 1
let minimumCellWidth: CGFloat = 120
let collectionViewWidth = collectionView!.bounds.size.width
// Calculate other required constants
let itemsInOneLine = CGFloat(Int((collectionViewWidth - CGFloat(Int(collectionViewWidth / minimumCellWidth) - 1) * itemSpacing) / minimumCellWidth))
let width = collectionViewWidth - itemSpacing * (itemsInOneLine - 1)
let cellWidth = floor(width / itemsInOneLine)
let realItemSpacing = itemSpacing + (width / itemsInOneLine - cellWidth) * itemsInOneLine / max(1, itemsInOneLine - 1)
// Apply values
flow.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
flow.itemSize = CGSize(width: cellWidth, height: cellWidth)
flow.minimumInteritemSpacing = realItemSpacing
flow.minimumLineSpacing = realItemSpacing
// Apply flow layout
collectionView?.setCollectionViewLayout(flow, animated: false)
【讨论】:
itemsInOneLine 为 1,那么这将导致 NaN,因为这里除以零:itemsInOneLine / (itemsInOneLine - 1)
斯威夫特 4
let flow = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
// If you create collectionView programmatically then just create this flow by UICollectionViewFlowLayout() and init a collectionView by this flow.
let itemSpacing: CGFloat = 3
let itemsInOneLine: CGFloat = 3
flow.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
//collectionView.frame.width is the same as UIScreen.main.bounds.size.width here.
let width = UIScreen.main.bounds.size.width - itemSpacing * CGFloat(itemsInOneLine - 1)
flow.itemSize = CGSize(width: floor(width/itemsInOneLine), height: width/itemsInOneLine)
flow.minimumInteritemSpacing = 3
flow.minimumLineSpacing = itemSpacing
编辑
如果要横向改为scrollDirction:
flow.scrollDirection = .horizontal
注意
如果您在一行中设置的项目不正确,请检查您的集合视图是否有填充。那就是:
let width = UIScreen.main.bounds.size.width - itemSpacing * CGFloat(itemsInOneLine - 1)
应该是collectionView的宽度。
【讨论】:
collectionView 的backgroundColor。或任何超级视图。
您可以为您的UICollectionView 使用collectionView:layout:insetForSectionAtIndex: 方法或设置附加到您的UICollectionView 的UICollectionViewFlowLayout 对象的sectionInset 属性:
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(top, left, bottom, right);
}
或
UICollectionViewFlowLayout *aFlowLayout = [[UICollectionViewFlowLayout alloc] init];
[aFlowLayout setSectionInset:UIEdgeInsetsMake(top, left, bottom, right)];
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 25, left: 15, bottom: 0, right: 5)
}
【讨论】:
UICollectionViewDelegateFlowLayout 添加到 ViewController 委托列表中以使用方法 insetForSectionAtIndex
设置附加到您的UICollectionView 的UICollectionViewFlowLayout 对象的insetForSectionAt 属性
确保添加此协议
UICollectionViewDelegateFlowLayout
斯威夫特
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets (top: top, left: left, bottom: bottom, right: right)
}
目标 - C
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
return UIEdgeInsetsMake(top, left, bottom, right);
}
【讨论】:
在 swift 4 和 autoLayout 中,您可以像这样使用 sectionInset:
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: (view.frame.width-40)/2, height: (view.frame.width40)/2) // item size
layout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10) // here you can add space to 4 side of item
collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout) // set layout to item
collectionView?.register(ProductCategoryCell.self, forCellWithReuseIdentifier: cellIdentifier) // registerCell
collectionView?.backgroundColor = .white // background color of UICollectionView
view.addSubview(collectionView!) // add UICollectionView to view
【讨论】:
在 Objective-C 中
CGFloat spacing = 5;
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*)_habbitCollectionV.collectionViewLayout;
flow.sectionInset = UIEdgeInsetsMake(0, spacing, 0, spacing);
CGFloat itemsPerRow = 2;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat oneMore = itemsPerRow + 1;
CGFloat width = screenRect.size.width - spacing * oneMore;
CGFloat height = width / itemsPerRow;
flow.itemSize = CGSizeMake(floor(height), height);
flow.minimumInteritemSpacing = spacing;
flow.minimumLineSpacing = spacing;
您所要做的就是更改 itemsPerRow 值,它会相应地更新每行的项目数。此外,如果您想要更多或更少的一般间距,您可以更改间距值。
【讨论】:
要为指定单元格添加边距,您可以使用此自定义流布局。 https://github.com/voyages-sncf-technologies/VSCollectionViewCellInsetFlowLayout/
extension ViewController : VSCollectionViewDelegateCellInsetFlowLayout
{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForItemAt indexPath: IndexPath) -> UIEdgeInsets {
if indexPath.item == 0 {
return UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
}
return UIEdgeInsets.zero
}
}
【讨论】:
在整个上添加间距UICollectionView:
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) collection.collectionViewLayout;
flow.sectionInset = UIEdgeInsetsMake(topMargin, left, bottom, right);
使用同一行(水平滚动时为列)的元素之间之间的间距及其大小:
flow.itemSize = ...;
flow.minimumInteritemSpacing = ...;
【讨论】:
collection.collectionViewLayout 需要像@Pooja 的示例中那样进行转换:UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) self.collectionViewLayout;
if let flow = collectionViewLayout as? UICollectionViewFlowLayout { flow.itemSize = CGSize(width: 100, height: 100) }
使用collectionViewFlowLayout.sectionInset 或collectionView:layout:insetForSectionAtIndex: 是正确的。
但是,如果您的 collectionView 有多个部分,并且您想为整个 collectionView 添加边距,我建议使用 scrollView contentInset :
UIEdgeInsets collectionViewInsets = UIEdgeInsetsMake(50.0, 0.0, 30.0, 0.0);
self.collectionView.contentInset = collectionViewInsets;
self.collectionView.scrollIndicatorInsets = UIEdgeInsetsMake(collectionViewInsets.top, 0, collectionViewInsets.bottom, 0);
【讨论】:
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(7, 10, 5, 10);
}
【讨论】:
要在每个部分之间添加 10px 的间隔,只需编写此代码
flowLayout.sectionInset = UIEdgeInsetsMake(0.0, 0.0,10,0);
【讨论】:
在 Interface Builder 中设置插入,如下面的屏幕截图所示
会产生这样的结果:
【讨论】:
要在CollectionItems 之间放置空格,请使用此
在viewdidload中写下这两行
UICollectionViewFlowLayout *collectionViewLayout = (UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout;
collectionViewLayout.sectionInset = UIEdgeInsetsMake(<CGFloat top>, <CGFloat left>, <CGFloat bottom>, <CGFloat right>)
【讨论】:
只是为了更正此页面中的一些错误信息:
1- minimumInteritemSpacing:在同一行中的项目之间使用的最小间距。
默认值:10.0。
(对于垂直滚动的网格,该值表示同一行中项目之间的最小间距。)
2- minimumLineSpacing :网格中项目行之间使用的最小间距。
【讨论】:
在UICollectionViewFlowLayout-Object 上使用setMinimumLineSpacing: 和setMinimumInteritemSpacing:。
【讨论】: