在 UICollectionView 中显示图像 - 如何实现图像之间的固定垂直间距?
Posted
技术标签:
【中文标题】在 UICollectionView 中显示图像 - 如何实现图像之间的固定垂直间距?【英文标题】:Display images in a UICollectionView - how to achieve fixed vertical spacing between images? 【发布时间】:2013-01-23 15:12:16 【问题描述】:我正在使用 UICollectionView 在 iPhone 应用程序 (ios6) 中呈现图像网格。
我正在为 UICollectionView 使用垂直滚动,并且图像都有固定的宽度和不同的高度。图像的宽度设置为在 iPhone 上显示 3 列图像。这工作正常,我得到了网格视图中显示的图像。
但是,由于我的图像具有不同的高度,因此一列中图像之间的垂直间距会发生变化,这看起来不太好,如下图所示(用 html 制作的模型):
我希望实现更流畅的流动,其中一列中图像之间的垂直间距相同。以下模型展示了我希望它如何工作:
关于如何解决这个问题的任何想法?
另外,作为一个额外的问题,如果应用程序不是为 iOS6 构建的(因为 UICollectionView 仅在 iOS6 中可用),是否有人知道解决相同问题的方法。通过使用 3rd 方组件或通过标准 iOS 控件解决它。
【问题讨论】:
【参考方案1】:子类 UICollectionViewFlowLayout 并在该类中添加这些方法。 (请注意,这假定为垂直方向,它会跳过第一行,并且它们之间是一个恒定的 10 像素。如果您需要水平版本,请参阅:how do you determine spacing between cells in 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;
【讨论】:
感谢您的帮助!对于其他人来说,答案解决方案有效。最后,我最终改用了第 3 方组件github.com/ptshih/PSCollectionView。这让我也可以瞄准 iOS5。 我知道如何给间距。但是如何在上面的代码中设置单个单元格的大小? @Satyamsvv 在 ViewController 类(不是布局子类)中使用 UICollectionViewFlowLayout 的委托方法 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)索引路径 这对任何人都有效吗?我弄得一团糟。Use of unresolved identifier 'sectionInset'
编译上述代码时出错。同样在for atts:UICollectionViewLayoutAttributes in arr!
崩溃,因为arr
是nil
。使用它的 Swift 版本。【参考方案2】:
对于 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
【讨论】:
Use of unresolved identifier 'sectionInset'
编译上述代码时出错。同样在for atts:UICollectionViewLayoutAttributes in arr!
崩溃,因为arr
是nil
。以上是关于在 UICollectionView 中显示图像 - 如何实现图像之间的固定垂直间距?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 UICollectionview 中显示前 9 张图像?
快速在 UICollectionView 中显示多个图像上传的进度条
图像未显示在 NSMutableArray 的 UICollectionView 中
当异步添加新项目时,UICollectionView 快速滚动在单元格中显示错误的图像