在UICollectionView中显示图像 – 如何实现图像之间的固定垂直间距?

我正在使用UICollectionView在iPhone应用程序(iOS6)中呈现图像网格。

我正在使用垂直滚动的UICollectionView,图像都有固定的宽度和不同的高度。 图像的宽度设置为在iPhone上显示3列图像。 这工作正常,我得到的网格视图中呈现的图像。

但是,由于我的图像高度不同,因此列中图像之间的垂直间距会有所不同,这看起来不太好,如下图所示(使用HTML制作的模型):

显示图像当前布局的图像

我反而希望实现更stream畅的stream动,即列之间的垂直间距相同。 下面的模型显示了我希望如何工作:

我想如何使图像流动的例子

任何想法如何解决这个问题?

此外,作为一个奖金的问题,有没有人知道一种方法来解决同样的问题,如果应用程序不是为iOS6构build的(因为UICollectionView只在iOS6中可用)。 通过使用第三方组件或通过解决它与标准的iOS控件。

子类UICollectionViewFlowLayout并在该类中添加这些方法。 (注意,这是假定垂直方向,它跳过第一行,它是一个常数10像素之间。请参阅: 如何确定UICollectionView flowLayout中单元格之间的间距,如果您需要水平版本

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { NSArray* arr = [super layoutAttributesForElementsInRect:rect]; for (UICollectionViewLayoutAttributes* atts in arr) { if (nil == atts.representedElementKind) { NSIndexPath* ip = atts.indexPath; atts.frame = [self layoutAttributesForItemAtIndexPath:ip].frame; } } return arr; } - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { UICollectionViewLayoutAttributes* atts = [super layoutAttributesForItemAtIndexPath:indexPath]; if (indexPath.item == 0 || indexPath.item == 1) // degenerate case 1, first item of section return atts; NSIndexPath* ipPrev = [NSIndexPath indexPathForItem:indexPath.item-2 inSection:indexPath.section]; CGRect fPrev = [self layoutAttributesForItemAtIndexPath:ipPrev].frame; CGFloat rightPrev = fPrev.origin.y + fPrev.size.height + 10; if (atts.frame.origin.y <= rightPrev) // degenerate case 2, first item of line return atts; CGRect f = atts.frame; f.origin.y = rightPrev; atts.frame = f; return atts; } 

对于Swift 3,这个代码适用于我,包括第一行的空间。

 override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { let arr = super.layoutAttributesForElements(in: rect) for atts:UICollectionViewLayoutAttributes in arr! { if nil == atts.representedElementKind { let ip = atts.indexPath atts.frame = (self.layoutAttributesForItem(at: ip)?.frame)! } } return arr } override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { let atts = super.layoutAttributesForItem(at: indexPath) if indexPath.item == 0 || indexPath.item == 1 { var frame = atts?.frame; frame?.origin.y = sectionInset.top; atts?.frame = frame!; return atts } let ipPrev = IndexPath(item: indexPath.item - 2, section: indexPath.section) let fPrev = self.layoutAttributesForItem(at: ipPrev)?.frame let rightPrev = (fPrev?.origin.y)! + (fPrev?.size.height)! + 10 if (atts?.frame.origin.y)! <= rightPrev { return atts } var f = atts?.frame f?.origin.y = rightPrev atts?.frame = f! return atts }