ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

6. UICollectionView Decoration View

2020-12-09 12:02:06  阅读:266  来源: 互联网

标签:attribute UICollectionView self 视图 Decoration let section frame View


6. UICollectionView Decoration View

UICollectionView 允许我们为每一个section、cell甚至是整个collectionView添加一个装饰视图。这玩意怎么说呢,就是添加了一些可复用视图,视图的frame可以随意设置,划重点是随意设置。

1.给section添加一张背景图片

实现装饰视图需要自定义layout,这里选择集成UICollectionViewFlowLayout,为了省去cell的布局实现

class CZDecorationFlowLayout: UICollectionViewFlowLayout {
    let decorationViewKind = "CZDecorationView"
    var itemsAttribute = [UICollectionViewLayoutAttributes]()
    var cz_delegate: CZDecorationFlowLayoutDelegate?
    
    override func prepare() {
        super.prepare()
        // 注册装饰视图
        self.register(CZDecorationView.self, forDecorationViewOfKind: decorationViewKind)
        // 获取section数量
        let sections = self.collectionView?.numberOfSections ?? 0
        
        // 给每一个section添加装饰视图的布局属性
        for i in 0..<sections {
            let attribute = CZDecorationAttributes.init(forDecorationViewOfKind: decorationViewKind, with: IndexPath(item: 0, section: i))
            attribute.zIndex = -1
            attribute.imageName = self.cz_delegate?.layout(self, decorationImageAt: i)
            
            if let count = self.collectionView?.numberOfItems(inSection: i), count > 0 {
                let firstItem = self.layoutAttributesForItem(at: IndexPath(item: 0, section: i))
                let lastItem = self.layoutAttributesForItem(at: IndexPath(item: (count - 1), section: i))
                let height = lastItem!.frame.maxY - firstItem!.frame.minY
                attribute.frame = CGRect(x: 0, y: firstItem!.frame.minY, width: self.collectionView!.frame.size.width, height: height)
                self.itemsAttribute.append(attribute)
            }
        }
        
    }
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        var attributes = super.layoutAttributesForElements(in: rect)
        for attribute in self.itemsAttribute {
            if rect.intersects(attribute.frame) {
                attributes?.append(attribute)
            }
        }
        return attributes
    }
}

重写prepare方法,此时一定要调用super.prepare(),否则会出问题。这里的代理是为了获取不同section中的图片,装饰视图的frame可以随意设置,因为要给section添加背景,我们选择从第一个cell到最后一个cell,且宽度等于collectionView的宽度,将布局属性添加到数组中,后续在layoutAttributesForElements(in rect: CGRect)中将其追加到collectionView子视图的布局属性数组中

class CZDecorationView: UICollectionReusableView {

    var imageView = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.addSubview(imageView)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
        super.apply(layoutAttributes)
        self.imageView.frame = layoutAttributes.bounds
        let attributes = layoutAttributes as! CZDecorationAttributes
        if let name = attributes.imageName {
            self.imageView.image = UIImage(named: name)
        }
    }
}

最重要的是apply(_ layoutAttributes: UICollectionViewLayoutAttributes),在这里我们将对视图中的子视图设置数据。

到此就完成了一个section的背景添加
sectiont添加背景图片

2.给cell添加背景图片

对于上面的代码,我们只需要改一下装饰视图的布局属性即可

let itemCount = self.collectionView?.numberOfItems(inSection: i) ?? 0
for item in 0..<itemCount {
    let indexPath = IndexPath(item: item, section: i)
    let attribute = CZDecorationAttributes.init(forDecorationViewOfKind: decorationViewKind, with: indexPath)
    attribute.zIndex = -1
    attribute.imageName = self.cz_delegate?.layout(self, decorationImageAt: indexPath)
    let itemAttributes = self.layoutAttributesForItem(at: indexPath)!
    attribute.frame = itemAttributes.frame
    self.itemsAttribute.append(attribute)
}

cell添加背景图片

3.collectionView可滚动范围添加背景图片

if let itemCountInSection = self.collectionView?.numberOfItems(inSection: (sections - 1)), itemCountInSection > 0 {
    let firstItem = self.layoutAttributesForItem(at: IndexPath(item: 0, section: 0))
    let lastItem = self.layoutAttributesForItem(at: IndexPath(item: (itemCountInSection - 1), section: (sections - 1)))
    let indexPath = IndexPath(item: 0, section: 0)
    let attribute = CZDecorationAttributes.init(forDecorationViewOfKind: decorationViewKind, with: indexPath)
    attribute.zIndex = -1
    attribute.imageName = "6"
    let height = lastItem!.frame.maxY - firstItem!.frame.minY
    attribute.frame = CGRect(x: 0, y: 0, width: self.collectionView!.frame.size.width, height: height)
    self.itemsAttribute.append(attribute)
}

collectionView可滚动范围添加背景图片

4. 总结

关于collection的装饰视图,核心步骤:

  1. 创建集成自UICollectionReusableView的自定义视图
  2. func apply(_ layoutAttributes: UICollectionViewLayoutAttributes)中补充显示逻辑
  3. 创建自定义layout,在func prepare()中编写装饰视图的布局属性(最为重要,控制装饰视图的显示的位置及尺寸)

5.代码地址

小小个子大个头

标签:attribute,UICollectionView,self,视图,Decoration,let,section,frame,View
来源: https://www.cnblogs.com/4zjq/p/14107802.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有