UICollectionView间距边距

我有一个显示照片的UICollectionView。我已使用UICollectionViewFlowLayout创建了CollectionView.它工作得很好,但我想在页边距上有间距。是否可以使用UICollectionViewFlowLayout或我必须实施自己的UICollectionViewLayout来完成此操作?

247956 次浏览

UICollectionViewFlowLayout-对象上使用setMinimumLineSpacing:setMinimumInteritemSpacing:

您可以对UICollectionView使用collectionView:layout:insetForSectionAtIndex:方法,或设置附加到UICollectionViewUICollectionViewFlowLayout对象的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)];

针对斯威夫特5进行更新

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 25, left: 15, bottom: 0, right: 5)
}

要在完全的UICollectionView上添加间距:

UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) collection.collectionViewLayout;
flow.sectionInset = UIEdgeInsetsMake(topMargin, left, bottom, right);

要使用间距_ABC_同一行(如果水平滚动,则为列)的0个元素及其大小:

flow.itemSize = ...;
flow.minimumInteritemSpacing = ...;

要在CollectionItem之间放置空格,请使用此

在viewdidload中写下这两行

UICollectionViewFlowLayout *collectionViewLayout = (UICollectionViewFlowLayout*)self.collectionView.collectionViewLayout;
collectionViewLayout.sectionInset = UIEdgeInsetsMake(<CGFloat top>, <CGFloat left>, <CGFloat bottom>, <CGFloat right>)

只是为了更正此页面中的一些错误信息:

1-最小项间距同一行中的项之间使用的最小间距。

默认值:10.0。

(对于垂直滚动网格,此值表示同一行中项目之间的最小间距。)

2-最小线间距网格中项目行之间使用的最小间距。

参考:http://developer.apple.com/library/ios/#documentation/uikit/reference/UICollectionViewFlowLayout_class/Reference/Reference.html

在Interface Builder中设置插图,如下面的屏幕截图所示

Setting section insets for UICollectionView

将导致类似这样的结果:

A collection view cell with section insets

要在每个部分之间添加10px的间隔,只需编写以下内容

flowLayout.sectionInset = UIEdgeInsetsMake(0.0, 0.0,10,0);
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(7, 10, 5, 10);
}

斯威夫特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宽度。

enter image description here

使用collectionViewFlowLayout.sectionInsetcollectionView: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);

要向指定的单元格添加边距,可以使用此自定义流动布局。 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
}
}

现代Swift,自动布局计算

虽然这个帖子已经包含了一堆有用的答案,但我想根据William Hu的答案添加一个现代雨燕版本。它还改善了两件事:

  • 现在,不同行之间的间距将始终与同一行中项目之间的间距相匹配。
  • 通过设置最小宽度, 代码自动计算一行中的项数,并 将该样式应用于流布局。

代码如下:

// 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)

在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值,它就会相应地更新每行的项数。此外,如果需要更多或更少的常规间距,可以更改间距值。

enter image description here enter image description here

在Swift 4和AutoLayout中,您可以像这样使用章节插图

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

设置附加到UICollectionViewUICollectionViewFlowLayout对象的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);
}