如何将背景图像添加到 UICollectionView 将滚动和缩放单元格
Posted
技术标签:
【中文标题】如何将背景图像添加到 UICollectionView 将滚动和缩放单元格【英文标题】:How to add a background image to UICollectionView that will scroll and zoom will cells 【发布时间】:2014-01-16 12:29:40 【问题描述】:我正在使用UICollectionView
构建马赛克视图。
我已将UICollectionViewFlowLayout
子类化为布局一个可以水平和垂直滚动 的固定网格。我还附上了一个UIPinchGestureRecognizer
,以便集合可以缩放/缩放。
集合中的每个单元格都包含一个具有一定透明度的UIImage
。我想添加一个可以随单元格滚动和缩放的背景图像。
我尝试了许多不同的解决方案。
使用colorWithPatternImage
设置UICollectionView
的背景颜色。 (不随内容滚动/调整大小)
将每个单元格上的背景图像视图设置为背景图像的相关裁剪部分。 (占用太多内存)
我一直在研究补充和装饰视图,但很难理解它。我想我需要使用 Supplementary 视图,因为背景中使用的图像会根据datasource
而改变。
我不明白的是如何只注册一个补充视图来跨越整个collectionview
的宽度和高度。它们似乎与indexPath
即每个单元格相关联。
【问题讨论】:
一个潜在的解决方案可能是将图像放在集合视图后面的滚动视图中,并且每次用户滚动集合视图时,您手动设置背景滚动视图以匹配。 感谢@nhgrif,这是我考虑过的一种解决方案,但似乎有点不雅。 【参考方案1】:不知道你有没有找到答案...!
您想要使用补充视图的方法是正确的。补充视图的索引路径不绑定到单元格,它有自己的索引路径。
然后在UICollectionViewFlowLayout
的子类中,您需要对一些方法进行子类化。 docs 还不错!
在layoutAttributesForElementsInRect:
方法中,您需要调用 super,然后为补充视图添加另一组布局属性。
然后在layoutAttributesForSupplementaryViewOfKind:atIndexPath:
方法中,将返回属性的大小设置为集合视图内容的大小,以便图像填充所有内容,而不仅仅是框架。您可能还想将 z 顺序设置为,以确保它位于单元格后面。请参阅UICollectionViewLayoutAttributes 的文档
@implementation CustomFlowLayout
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
NSMutableArray *attributes = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
// Use your own index path and kind here
UICollectionViewLayoutAttributes *backgroundLayoutAttributes = [self layoutAttributesForSupplementaryViewOfKind:@"background" atIndexPath:[NSIndexPath indexPathWithItem:0 inSection:0]];
[attributes addObject:backgroundLayoutAttributes];
return [attributes copy];
-(UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
if ([kind isEqualToString:@"background"])
UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:kind withIndexPath:indexPath];
attrs.size = [self collectionViewContentSize];
attrs.zIndex = -10;
return attrs;
else
return [super layoutAttributesForSupplementaryViewOfKind:kind atIndexPath:indexPath];
@end
在您的集合视图数据源中,您需要此方法:
collectionView:viewForSupplementaryElementOfKind:atIndexPath:
-(void)viewDidLoad
[super viewDidLoad];
// Setup your collection view
UICollectionView *collectionView = [UICollectionView initWithFrame:self.view.bounds collectionViewLayout:[CustomFlowLayout new]];
[collectionView registerClass:[BackgroundReusableView class] forSupplementaryViewOfKind:@"background" withReuseIdentifier:@"backgroundView"];
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
if ([kind isEqualToString:@"background"])
BackgroundReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"backgroundView" forIndexPath:indexPath];
// Set extra info
return view;
else
// Shouldn't be called
return nil;
希望所有这些都能让你走上正轨:)
【讨论】:
感谢 Rich 的帮助,太好了,我会试一试!【参考方案2】:在 Swift 5 中实现 CollectionView 中的自定义部分背景,
class CustomFlowLayout: UICollectionViewFlowLayout
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]?
var attributes = super.layoutAttributesForElements(in: rect)
for section in 0..<collectionView!.numberOfSections
let backgroundLayoutAttributes:UICollectionViewLayoutAttributes = layoutAttributesForSupplementaryView(ofKind: "background", at: IndexPath(item: 0, section: section)) ?? UICollectionViewLayoutAttributes()
attributes?.append(backgroundLayoutAttributes)
return attributes
override func layoutAttributesForSupplementaryView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes?
let attrs = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: elementKind, with: indexPath)
if elementKind == "background"
attrs.size = collectionView!.contentSize
//calculate frame here
let items = collectionView!.numberOfItems(inSection: indexPath.section)
let totalSectionHeight:CGFloat = CGFloat(items * 200)
let cellAttr = collectionView!.layoutAttributesForItem(at: indexPath)
attrs.frame = CGRect(x: 0, y: cellAttr!.frame.origin.y, width: collectionView!.frame.size.width, height: totalSectionHeight)
attrs.zIndex = -10
return attrs
else
return super.layoutAttributesForSupplementaryView(ofKind: elementKind, at: indexPath)
在您的 CollectionView 数据源中,
override func viewDidLoad()
super.viewDidLoad()
//register collection view here
...
//setup flow layout & register supplementary view
let customFlowLayout = CustomFlowLayout()
collectionView.collectionViewLayout = customFlowLayout
collectionView.register(UINib(nibName: "BackgroundReusableView", bundle: nil), forSupplementaryViewOfKind: "background", withReuseIdentifier: "BackgroundReusableView")
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
if kind == "background"
let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "BackgroundReusableView", for: indexPath) as! BackgroundReusableView
return view
return UICollectionReusableView()
【讨论】:
以上是关于如何将背景图像添加到 UICollectionView 将滚动和缩放单元格的主要内容,如果未能解决你的问题,请参考以下文章
如何将背景图像添加到 UICollectionView 将滚动和缩放单元格