41

在 UICollectionView 中,我想为整个部分提供统一的背景颜色,而不是为单个单元格或整个集合视图。

我没有看到任何委托方法可以做到这一点,有什么建议吗?

4

10 回答 10

6

UICollectionViewCompositionalLayoutiOS 13 中引入的新属性有一个名为decorationItems方便添加装饰项目的属性,您可以使用该属性为该部分添加背景。

let section = NSCollectionLayoutSection(group: group)
section.decorationItems = [
   NSCollectionLayoutDecorationItem.background(elementKind:"your identifier")
]
于 2020-05-05T08:37:01.680 回答
3

这个想法是覆盖UICollectionViewLayoutAttributes以添加颜色属性。然后覆盖UICollectionReusableView将颜色应用于视图背景。

https://github.com/strawberrycode/SCSectionBackground

于 2016-09-19T18:10:29.863 回答
2

我还没有尝试过,但在我看来,如果你想要单元格后面的背景(比如 Books 应用程序中的书架),你需要使用装饰视图。我认为您应该能够为每个部分拥有不同的视图,并使用委托方法进行设置layoutAttributesForDecorationViewOfKind:atIndexPath:

于 2012-11-28T17:34:19.240 回答
2

首先,将 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
}

这些文档链接帮助了我:

于 2021-10-08T17:31:33.600 回答
1

参考:
草莓代码:使用DecorationView作为背景
devxoul:使用SupplementaryElement作为背景
airbnb:使用SupplementaryElement作为背景

我需要兼容IGListKit,所以我decorationView用作背景。布局是UICollectionViewFlowLayout常见用例的子类。我的实现不同的部分背景

于 2019-09-17T04:31:41.630 回答
0

在集合视图中,每个部分都可以有一个补充视图,因此为每个部分放置补充视图,然后将背景颜色设置为补充视图而不是部分单元格。我希望它会有所帮助。

于 2013-12-03T14:06:15.823 回答
0

一种经典的方法是创建一个自定义补充种类并在 CollectionView 部分背景中提供您的自定义视图。它将使您能够自定义部分背景。参考https://stackoverflow.com/a/63598373/14162081

于 2020-08-26T13:13:22.370 回答
-1

我在这里离开了这个回购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 中的高度。你应该为你自己的项目改变它。

于 2017-08-08T15:38:35.817 回答
-1

它非常简单,只需使用这个默认的 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

}
于 2019-08-06T22:20:15.673 回答
-4

我在以下方法中以非常简单的方式更改了每个部分的背景颜色: 但我不确定这样做是否正确。但它确实奏效了。

- (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;
}
于 2016-02-29T04:58:12.883 回答