经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
6. UICollectionView Decoration View
来源:cnblogs  作者:小小个子大个头  时间:2020/12/14 17:18:49  对本文有异议

6. UICollectionView Decoration View

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

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

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

  1. class CZDecorationFlowLayout: UICollectionViewFlowLayout {
  2. let decorationViewKind = "CZDecorationView"
  3. var itemsAttribute = [UICollectionViewLayoutAttributes]()
  4. var cz_delegate: CZDecorationFlowLayoutDelegate?
  5. override func prepare() {
  6. super.prepare()
  7. // 注册装饰视图
  8. self.register(CZDecorationView.self, forDecorationViewOfKind: decorationViewKind)
  9. // 获取section数量
  10. let sections = self.collectionView?.numberOfSections ?? 0
  11. // 给每一个section添加装饰视图的布局属性
  12. for i in 0..<sections {
  13. let attribute = CZDecorationAttributes.init(forDecorationViewOfKind: decorationViewKind, with: IndexPath(item: 0, section: i))
  14. attribute.zIndex = -1
  15. attribute.imageName = self.cz_delegate?.layout(self, decorationImageAt: i)
  16. if let count = self.collectionView?.numberOfItems(inSection: i), count > 0 {
  17. let firstItem = self.layoutAttributesForItem(at: IndexPath(item: 0, section: i))
  18. let lastItem = self.layoutAttributesForItem(at: IndexPath(item: (count - 1), section: i))
  19. let height = lastItem!.frame.maxY - firstItem!.frame.minY
  20. attribute.frame = CGRect(x: 0, y: firstItem!.frame.minY, width: self.collectionView!.frame.size.width, height: height)
  21. self.itemsAttribute.append(attribute)
  22. }
  23. }
  24. }
  25. override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
  26. var attributes = super.layoutAttributesForElements(in: rect)
  27. for attribute in self.itemsAttribute {
  28. if rect.intersects(attribute.frame) {
  29. attributes?.append(attribute)
  30. }
  31. }
  32. return attributes
  33. }
  34. }

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

  1. class CZDecorationView: UICollectionReusableView {
  2. var imageView = UIImageView()
  3. override init(frame: CGRect) {
  4. super.init(frame: frame)
  5. self.addSubview(imageView)
  6. }
  7. required init?(coder: NSCoder) {
  8. fatalError("init(coder:) has not been implemented")
  9. }
  10. override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
  11. super.apply(layoutAttributes)
  12. self.imageView.frame = layoutAttributes.bounds
  13. let attributes = layoutAttributes as! CZDecorationAttributes
  14. if let name = attributes.imageName {
  15. self.imageView.image = UIImage(named: name)
  16. }
  17. }
  18. }

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

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

2.给cell添加背景图片

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

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

cell添加背景图片

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

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

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

4. 总结

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

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

5.代码地址

小小个子大个头

原文链接:http://www.cnblogs.com/4zjq/p/14107802.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号