UICollectionView间距边距


181

我有一个UICollectionView显示照片的。我使用创建了collectionview UICollectionViewFlowLayout。效果不错,但我想在边距上留一些间距。是否可以使用UICollectionViewFlowLayout或我必须自己实现UICollectionViewLayout

Answers:


331

您可以使用的collectionView:layout:insetForSectionAtIndex:方法,UICollectionView或设置附加到sectionInsetUICollectionViewFlowLayout对象的属性UICollectionView

- (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)];

已为Swift 5更新

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

35
使用垂直流布局时,我似乎并没有获得左右插图的工作……
John

1
现在,重写子类UICollectionViewFlowLayout的sectionInset方法也无效。如下所述设置属性。
德伦(Dren)

4
注意:记住要添加UICollectionViewDelegateFlowLayout到ViewController委托列表中以使用该方法insetForSectionAtIndex
David Douglas

98

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

设置UICollectionView的部分插图

将导致如下所示:

具有部分插图的集合视图单元格


2
很好的答案,只是想指出,您还必须以最小的间距播放,以使部分插图效果良好。
史密斯·亚什

75

要在整体 上增加间距UICollectionView

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

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

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

5
collection.collectionViewLayout是可行的,但需要像@Pooja的示例中那样进行强制转换: UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*) self.collectionViewLayout;
jwj 2013年

快速投放if let flow = collectionViewLayout as? UICollectionViewFlowLayout { flow.itemSize = CGSize(width: 100, height: 100) }
2016年

41

斯威夫特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)
    let width = UIScreen.main.bounds.size.width - itemSpacing * CGFloat(itemsInOneLine - 1) //collectionView.frame.width is the same as  UIScreen.main.bounds.size.width here.
    flow.itemSize = CGSize(width: floor(width/itemsInOneLine), height: width/itemsInOneLine)
    flow.minimumInteritemSpacing = 3
    flow.minimumLineSpacing = 3

编辑 XCode 11.4和Swift 5

let flow = collectionView.collectionViewLayout as! UICollectionViewFlowLayout

不起作用。使用以下作品。

let flow = UICollectionViewFlowLayout()

在此处输入图片说明


有没有办法将颜色设置为间距?
马丁·丹尼尔

1
@MartínDaniel只需设置backgroundColor的即可collectionView。或任何超级视图。
William Hu

1
但边缘没有边距
user924 '19

@ user924可以使用UIEdgeInsets(top:left:bottom:right:)设置边缘的边距。如果垂直滚动,请设置左/右插图。如果水平滚动,请设置顶部和底部插图。
马西

40

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

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

默认值:10.0。

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

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

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


2
这似乎并不影响各节之间的间距,仅影响同一节内的项目之间的间距?
Crashalot

@Crashalot-您确定您不是指minimumLineSpacing吗?即每行细胞?如果您确实在使用节,则还有节插入的选项。
Chucky

这对我来说是通过情节提要界面实现的。我一直在寻找仅水平收集视图的解决方案。谢谢+10
kemicofa鬼

9

快速,自动布局计算

尽管该线程已经包含了许多有用的答案,但我想基于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)
TylerJames

1
@TylerJames谢谢!我调整了代码以解决此问题;)
fredpi

8

在-Object 上使用setMinimumLineSpacing:和。setMinimumInteritemSpacing:UICollectionViewFlowLayout


不,它不起作用,正如预期的那样。setMinimumLineSpacing是:在同一行中的项目之间使用的最小间距。并且setMinimumInteritemSpacing是:网格中项目行之间使用的最小间距。我的问题是关于边距而不是元素之间的空间。例如。第一个元素的左右间距。
Mert 2012年

假设垂直srollDirection,则可以将contentInset用于第一行和最后一行的顶部和底部间距。您也可以在单元格中添加边距。
乔纳森·希洪

8

使用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);

5

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

在viewdidload中写这两行

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

5

设置附加到您insetForSectionAtUICollectionViewFlowLayout对象的属性UICollectionView

确保添加此协议

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);
}

2

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

在此处输入图片说明 在此处输入图片说明


1
很好...工作完美。
sohil

1

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

0

在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

-1

要在每个部分之间添加10px的间距,只需编写此代码

flowLayout.sectionInset = UIEdgeInsetsMake(0.0, 0.0,10,0);

当使用UICollectionElementKindSectionFooter类型的UICollectionReusableView时,您的解决方案将无法使用
Pratik Jamariya

-1
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {       
         return UIEdgeInsetsMake(7, 10, 5, 10);    
   }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.