如何更改 UICollectionView 中整个部分的背景颜色?
Posted
技术标签:
【中文标题】如何更改 UICollectionView 中整个部分的背景颜色?【英文标题】:How to change background color of a whole section in UICollectionView? 【发布时间】:2012-11-16 13:09:08 【问题描述】:在 UICollectionView 中,我想为整个部分提供统一的背景颜色,而不是为单个单元格或整个集合视图。
我没有看到任何委托方法可以做到这一点,有什么建议吗?
【问题讨论】:
试试这个github.com/devxoul/UICollectionViewFlexLayout 【参考方案1】:ios 13 中引入的新UICollectionViewCompositionalLayout
有一个名为decorationItems
的属性,可以方便地添加装饰项,您可以使用该属性为该部分添加背景。
let section = NSCollectionLayoutSection(group: group)
section.decorationItems = [
NSCollectionLayoutDecorationItem.background(elementKind:"your identifier")
]
【讨论】:
【参考方案2】:想法是重写 UICollectionViewLayoutAttributes 以添加颜色属性。然后覆盖 UICollectionReusableView 将颜色应用到视图背景。
https://github.com/strawberrycode/SCSectionBackground
【讨论】:
当我制作这个示例以支持所有方向时,从纵向移动到横向移动或反之亦然,应用程序崩溃并出现以下错误, SCSectionBackground[34266:300939] *** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“索引路径处补充项目的布局属性(length = 2, path = 0 - 0 ) 从我还没有尝试过,但在我看来,如果您想要单元格后面的背景(例如 Books 应用程序中的书架),则需要使用装饰视图。我认为您应该能够为每个部分拥有不同的视图,并使用委托方法 layoutAttributesForDecorationViewOfKind:atIndexPath:
进行设置。
【讨论】:
【参考方案4】:参考:strawberrycode: Use DecorationView as backgrounddevxoul: Use SupplementaryElement as backgroundairbnb: Use SupplementaryElement as background
我需要兼容IGListKit
,所以我使用decorationView
作为
背景。布局是UICollectionViewFlowLayout
的子类,用于常见用例。 My implementation:
【讨论】:
【参考方案5】:首先,将 UICollectionReusableView 作为背景视图。我只是将我的设置为红色。
class SectionBackgroundDecorationView: UICollectionReusableView
override init(frame: CGRect)
super.init(frame: frame)
self.backgroundColor = .red
required init?(coder: NSCoder)
fatalError("init(coder:) has not been implemented")
然后,在 YourCollectionViewController 中:
static let background = "background-element-kind"
init()
super.init(collectionViewLayout: YourCollectionViewController.createLayout())
static func createLayout() -> UICollectionViewLayout
let layout = UICollectionViewCompositionalLayout (sectionIndex: Int,
layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection? in
// Use sectionIndex to control the layout in each section
if sectionIndex == 0
// Customise itemSize, item, groupSize, group to be whatever you want
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .fractionalHeight(1))
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
heightDimension: .absolute(170))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
// Create a sectionBackground
let sectionBackground = NSCollectionLayoutDecorationItem.background(
elementKind: background)
section.decorationItems = [sectionBackground]
return section
else
// Your layout for other sections, etc
// You don't have to set a background for other sections if you don't want to
layout.register(SectionBackgroundDecorationView.self, forDecorationViewOfKind: background)
return layout
这些文档链接帮助了我:
https://developer.apple.com/documentation/uikit/nscollectionlayoutdecorationitem https://developer.apple.com/documentation/uikit/uicollectionviewcompositionallayoutsectionprovider【讨论】:
【参考方案6】:在集合视图中,每个部分都可以有一个补充视图,因此为每个部分放置补充视图,然后将背景颜色设置为补充视图而不是部分单元格。我希望它会有所帮助。
【讨论】:
在阅读补充视图时,我只找到用于页眉和页脚的示例。您是否有任何示例和/或工作代码可供您回答。 我已经通过使用集合视图自定义布局来完成它。在自定义布局中,我的补充视图框架等于整个剖面框架。 你是怎么做到的?如果你能说那会很棒。谢谢【参考方案7】:其中一种经典方法是创建自定义补充种类并在 CollectionView 部分背景中提供您的自定义视图。它将使您能够自定义部分背景。 参考https://***.com/a/63598373/14162081
【讨论】:
【参考方案8】:我在这里退出了这个 repo https://github.com/SebastienMichoy/CollectionViewsDemo/tree/master/CollectionViewsDemo/Sources/Collections%20Views
斯威夫特 3
子类 uicollectionreusableview
class SectionView: UICollectionReusableView
static let kind = "sectionView"
子类 uicollectionViewFlowLayout
class CustomFlowLayout: UICollectionViewFlowLayout
// MARK: Properties
var decorationAttributes: [IndexPath: UICollectionViewLayoutAttributes]
var sectionsWidthOrHeight: [IndexPath: CGFloat]
// MARK: Initialization
override init()
self.decorationAttributes = [:]
self.sectionsWidthOrHeight = [:]
super.init()
required init?(coder aDecoder: NSCoder)
self.decorationAttributes = [:]
self.sectionsWidthOrHeight = [:]
super.init(coder: aDecoder)
// MARK: Providing Layout Attributes
override func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes?
return self.decorationAttributes[indexPath]
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]?
var attributes = super.layoutAttributesForElements(in: rect)
let numberOfSections = self.collectionView!.numberOfSections
var xOrYOffset = 0 as CGFloat
for sectionNumber in 0 ..< numberOfSections
let indexPath = IndexPath(row: 0, section: sectionNumber)
let numberOfItems = self.collectionView?.numberOfItems(inSection: sectionNumber)
let sectionWidthOrHeight = numberOfItems == 0 ? UIScreen.main.bounds.height : collectionViewContentSize.height//self.sectionsWidthOrHeight[indexPath]!
let decorationAttribute = UICollectionViewLayoutAttributes(forDecorationViewOfKind: SectionView.kind, with: indexPath)
decorationAttribute.zIndex = -1
if self.scrollDirection == .vertical
decorationAttribute.frame = CGRect(x: 0, y: xOrYOffset, width: self.collectionViewContentSize.width, height: sectionWidthOrHeight)
else
decorationAttribute.frame = CGRect(x: xOrYOffset, y: 0, width: sectionWidthOrHeight, height: self.collectionViewContentSize.height)
xOrYOffset += sectionWidthOrHeight
attributes?.append(decorationAttribute)
self.decorationAttributes[indexPath] = decorationAttribute
return attributes
实现这个
CollectionView 委托函数
func collectionView(_ collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, at indexPath: IndexPath)
Log.printLog(identifier: elementKind, message: indexPath)
if elementKind == UICollectionElementKindSectionHeader, let view = view as? ProfileViewHeaderView
view.backgroundColor = UIColor(red: (102 / 255.0), green: (169 / 255.0), blue: (251 / 255.0), alpha: 1)
else if elementKind == SectionView.kind
let evenSectionColor = UIColor.black
let oddSectionColor = UIColor.red
view.backgroundColor = (indexPath.section % 2 == 0) ? evenSectionColor : oddSectionColor
这很重要
let layout = CustomFlowLayout()
layout.register(SectionView.self, forDecorationViewOfKind: SectionView.kind)
使用布局而不是 collectionView 注册 UICollectionReusableView。
还有一件事。我弄乱了 layoutAttributesForElements 中的高度。您应该为自己的项目更改它。
【讨论】:
【参考方案9】:很简单,只要使用这个默认的UICollectionViewDelegate的方法,就可以了
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath)
print(indexPath.item)
let evenSectionColor = UIColor.clear
let oddSectionColor = UIColor.white
cell.contentView.backgroundColor = (indexPath.item % 2 == 0) ? evenSectionColor : oddSectionColor
【讨论】:
【参考方案10】:我通过以下方法以非常简单的方式更改了每个部分的背景颜色:但我不确定这样做是否正确。但它确实奏效了。
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
FamilyCalendarCellItemCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"calendarItem" forIndexPath:indexPath];
Event *event;
_headerView = [collectionView dequeueReusableSupplementaryViewOfKind:
UICollectionElementKindSectionHeader withReuseIdentifier:@"EventHeader" forIndexPath:indexPath]; //headerView is declared as property of Collection Reusable View class
if(indexPath.section==0)
cell.backgroundColor=[UIColor orangeColor];
else if(indexPath.section==1)
cell.backgroundColor=[UIColor yellowColor];
return cell;
【讨论】:
这只会改变单元格的背景颜色。问题是询问如何在给定部分中更改集合视图本身的背景颜色以上是关于如何更改 UICollectionView 中整个部分的背景颜色?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中更改 UICollectionView 的 targetContentOffset?
如何在 iOS 中动态更改 UICollectionView 单元格高度
如何更改 UICollectionView 中单元格之间的空间?