我正在使用UICollectionView
构建马赛克视图。
我已经将UICollectionViewFlowLayout
子类化为布局固定网格,可以同时滚动水平和垂直。我还附加了UIPinchGestureRecognizer
,因此集合可以缩放/缩放。
集合中的每个单元格都包含一个具有一定透明度的UIImage
。我想添加一个背景图像,用于滚动和缩放细胞。
我尝试了许多不同的解决方案。
UICollectionView
设置colorWithPatternImage
的背景颜色。 (不会滚动/调整内容)我一直在寻找补充和装饰视图,但努力让我的头围绕它。我想我需要使用补充视图,因为后台使用的图像会根据datasource
而改变。
我不明白的是我如何只注册一个补充视图来跨越整个collectionview
的宽度和高度。它们似乎与indexPath
相关联,即每个细胞。
答案 0 :(得分:4)
不知道你是否找到答案......!
你想要使用补充观点,你正走在正确的轨道上。补充视图的索引路径不依赖于单元格,它有自己的索引路径。
然后在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;
}
}
希望所有这些能让你走上正轨:)
答案 1 :(得分:1)
要在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()
}