Swift - 给UICollectionview设置组背景和圆角
钟情圆角怎么办
最近由于我们的UI钟情于圆角搞得我很方,各种圆角渐变,于是就有了下面这篇给UICollection组设置圆角和背景色的诞生,不知道在我们平时有没有遇到这样子的一些需求,就是按照每一组给UIColllectionView设置不同的背景色,要是没有遇到的同学建议可以先思考一下改怎么处理在看下面的内容吧。
首先需要考虑的是在哪里设置了,我们都应该知道关于CollectionView的属性几乎都是在Layout里面在管理的,那我们要给它设置背景色和院圆角也肯定是在在这去写的了,在大小间距等布局方面我们遵循的都是 UICollectionViewDelegateFlowLayout 这个代理,但这时候我们就应该想到这个DelegateFlowLayout里面没有设置背景色和圆角的代理的,我们需要背景色这个概念的话就只能去注册一个修饰View然后给修饰的View去设置背景色和圆角了。
// MARK: - 注册一个装饰View
func registClass() { self.register(PPReusableView.self, forDecorationViewOfKind: PPCollectionViewSectionBackground)
}
NOTE: PPReusableView.self 这个语法在OC中就等于[PPReusableView Class]
PPReusableView是继承与UICollectionReusableView这个装饰View,我们后面会说这个View 后面的 PPCollectionViewSectionBackground 就是我们平时像注册cell时候的一个 identify 而已。
重点
在我们写瀑布流或者别的一些布局的时候,我们都是在哪里重写的? 没错就是 prepare 方法, 我把这整个方法全都放出来看,注释写的很仔细的,要是有不理解的地方可以再留言Q我,具体的肯定是我们继承 UICollectionViewFlowLayout 写了,这里需要注意UICollectionViewFlowLayout和UICollectionViewDelegateFlowLayout,别搞混淆了。按照如下定义一个PPBaseFlowLayout继承与UICollectionViewFlowLayout,在里面我们重写prepare这个方法。
// MARK: - 重写 - prepare
// NOTE: 该方法会在你每次刷新collection data 的时候都会调用
override func prepare() {
super.prepare() self.layoutAttributes?.removeAll()
/// 有多少组
let numberOfSections = self.collectionView?.numberOfSections ?? 0
let delegate = self.collectionView?.delegate
/// 不存在就直接返回 没法再往下设置
guard (numberOfSections != 0) || !(delegate is PPCollectionViewDelegateFlowLayout) else {
return
}
// 循环遍历各组 设置添加的属性
for section in 0..<numberOfSections { /// 一组的Item
let numberOfItems = self.collectionView?.numberOfItems(inSection: section)
if (numberOfItems! <= 0) {
continue;
} /// 每一组第一个item的Attributes
let firstItem = self.layoutAttributesForItem(at: IndexPath.init(item: 0, section: section))
/// 每一组最后一个item的Attributes
let lastItem = self.layoutAttributesForItem(at: IndexPath.init(item: numberOfItems! - 1, section: section))
/// 满足条件 结束本次循环执行下一次
if ((firstItem == nil) || (lastItem == nil)) {
continue
}
if(delegate?.responds(to:#selector(UICollectionViewDelegateFlowLayout.collectionView(_:layout:insetForSectionAt:))))! { let inset = (delegate as? UICollectionViewDelegateFlowLayout)? .collectionView?(self.collectionView!, layout: self, insetForSectionAt: section)
self.sectionInset = inset!
} /// 获取第一个和最后一个item的联合frame ,得到的就是这一组的frame
var sectionFrame:CGRect = firstItem!.frame.union(lastItem!.frame)
/// 设置它的x.y
sectionFrame.origin.x -= self.sectionInset.left - 10
sectionFrame.origin.y -= self.sectionInset.top
///横向滚动
if self.scrollDirection == .horizontal{ /// 计算组的宽的时候要把缩进进去的距离加回来 因为缩进是内容缩进
sectionFrame.size.width += self.sectionInset.left + self.sectionInset.right
/// 横向滚动的时候 组的高就是collectionView的高
sectionFrame.size.height = self.collectionView!.frame.size.height
/// 纵向滚动
}else{
/// 纵向滚动的时候组的宽度
sectionFrame.size.width = self.collectionView!.frame.size.width-20
sectionFrame.size.height += self.sectionInset.top + self.sectionInset.bottom
}
/// 根据自定义的PPCollectionViewSectionBackground 装饰View初始化一个自定义的PPLayoutAttributes
let attribute = PPLayoutAttributes.init(forDecorationViewOfKind:PPCollectionViewSectionBackground,with: IndexPath.init(item: 0, section: section)) attribute.frame = sectionFrame
attribute.zIndex = -1
/// 背景色
attribute.backgroundColor = (delegate as? PPCollectionViewDelegateFlowLayout)?.backgroundColorForSection!(collectionView: self.collectionView!, layout: self, section: section)
/// 圆角
attribute.corners = (delegate as? PPCollectionViewDelegateFlowLayout)?.sessionBackgroundViewCornerscollectionView!(collectionView: self.collectionView!, layout: self, section: section)
self.layoutAttributes?.append(attribute)
}
}
NOTE:仔细看代码可以看到圆角和背景色的属性都是设置给PPLayoutAttributes,这玩意又是什么呢?就是我们CollectionView的属性管理者UICollectionViewLayoutAttributes,你进UICollectionViewLayoutAttributes可以看到它的属性有那些,不要忘记我们是根据修饰View初始化得到这个属性的,按照正常的操作我们会在最后返回一个属性数组,自定义过collection布局的应该清楚一些,具体的PPCollectionViewDelegateFlowLayout就是我们继承与UICollectionViewDelegateFlowLayout写的代理了,这个代理里面也就两个方法,圆角和颜色的设置,代码如下:
// MARK: - 可以在协议里面添加代理方法用于设置你想给CollectionView添加的属性设置值
@objc protocol PPCollectionViewDelegateFlowLayout:UICollectionViewDelegateFlowLayout{ /// 给CollectionView 的组设置背景颜色
///
/// - Parameters:
/// - collectionView: collectionView description
/// - layout: layout description
/// - section: section description
/// - Returns: return value description
@objc optional func backgroundColorForSection(collectionView:UICollectionView,
layout:UICollectionViewLayout,
section:NSInteger) -> UIColor /// 给CollectionView 的组设置圆角
///
/// - Parameters:
/// - collectionView: collectionView description
/// - layout: layout description
/// - section: section description
/// - Returns: UIRectCorner eg:[.topLeft,.topRight]
@objc optional func sessionBackgroundViewCornerscollectionView(collectionView:UICollectionView,
layout:UICollectionViewLayout,
section:NSInteger) -> UIRectCorner
}
说说这个PPLayoutAttributes吧
这个还真没法仔细说,因为....... 下面就是它的全部代码
import Foundation
import UIKit // MARK: - 这里可以给CollectionView 添加自定义属性
class PPLayoutAttributes: UICollectionViewLayoutAttributes { var backgroundColor:UIColor?
var corners:UIRectCorner?
}
不能忘记了PPReusableView,它的代码也比较的简单,如下
import Foundation
import UIKit // MARK: - 可重复使用视图
class PPReusableView: UICollectionReusableView { override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
super.apply(layoutAttributes) if layoutAttributes.isKind(of: PPLayoutAttributes.self) { let layoutAttribute = layoutAttributes as? PPLayoutAttributes
if layoutAttribute!.backgroundColor != nil {
self.backgroundColor = layoutAttribute!.backgroundColor
}
/// 默认设置为 12 以后有需要可以自定义
if layoutAttribute!.corners != nil {
self.setRoundingCorners(layoutAttribute!.corners!, cornerRadii: kDefaultCornerRadii)
}
}
}
}
可以了返回你的属性吧
随后就是返回你前面设置了那么多的属性,具体的就是下面的代码所示了
// MARK: - 重写 - layoutAttributesForElements 返回各组的属性
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { var attributes = super.layoutAttributesForElements(in: rect)
///
for attribute in self.layoutAttributes! { ///判断两个区域是否相交
if rect.intersects(attribute.frame){ attributes?.append(attribute)
}
}
return attributes
} // MARK: - 重写 - layoutAttributesForDecorationView 给装饰的View返回属性
/// Decorationview 装饰view
override func layoutAttributesForDecorationView(ofKind elementKind: String, at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { if elementKind == PPCollectionViewSectionBackground { return self.layoutAttributes![indexPath.section]
}
return super.layoutAttributesForDecorationView(ofKind: elementKind, at: indexPath)
}
最后:
最后我们在最前面说的registClass这个方法我们在PPBaseFlowLayout的初始化方法里面调用就可以了,还有属性数组这写就不用说了吧还是在前面自己定义初始化了。
然后上面代码里面的一些宏定义比如identify还有圆角大小等等这些就根据自己的需求去写吧。
最后在初始化CollectionView的时候layout就是我们定义的PPBaseFlowLayout了,遵守的代理就是PPCollectionViewDelegateFlowLayout,这个需要留意下就OK。
Swift - 给UICollectionview设置组背景和圆角的更多相关文章
- Android给TextView设置透明背景、圆角边框
第一种方法:在drawable文件夹下新建一个文件设置背景样式 代码: 在drawable文件夹下面新建text_view_border.xml <?xml version="1.0& ...
- Swift开发教程--设置UIViewController的背景透明
非常easy的一句代码 self.view.backgroundColor = UIColor.clearColor() 由此联想开来,非常多的控件想设置为背景透明都能够用UIColor.clearC ...
- Qt 之 设置窗口边框的圆角(使用QSS和PaintEvent两种方法)
Qt在设置窗口边框圆角时有两种方式,一种是设置样式,另一种是在paintEvent事件中绘制窗口.下面分别叙述用这两种方式来实现窗口边框圆角的效果. 一.使用setStyleSheet方法 this- ...
- iOS 11 导航栏 item 偏移问题 和 Swift 下 UIButton 设置 title、image 显示问题
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- APUE学习之三个特殊位 设置用户ID(set-user-ID),设置组ID(set-group-ID),sticky
设置用户ID(set-user-ID),设置组ID(set-group-ID),sticky set-user-ID: SUID 当文件的该位有设置时,表示当该文件被执行时,程序具有文件 ...
- 【转】linux 设置用户id 设置组id
linux 设置用户id 设置组id 转自 linux 设置用户id 设置组id 最近看apue,简单记录对设置用户id理解(设置组id同理). 1. 相关的id好像很多,共有哪些? 文件2个 ...
- Windows 7个性化配置,关闭Win7动画效果,设置窗口背景为“ 豆绿色”
减少眼睛疲劳配色(豆绿色): RGB:, , ,颜色名称:#C7EDCC 1.任务栏设置 2.关闭Win7动画效果 控制面板 -> 轻松访问 -> 优化视频显示 3.去掉窗口阴影 右键单击 ...
- 在IE6下使用filter设置png背景
今天帮别人解决问题学会了一个在IE6下使用filter设置png背景,具体css写法如下: .login_form_wrap { width: 778px; height: 360px; backgr ...
- 导航栏视图设置 tabbleView 是设置总背景图
//导航栏视图设置 tabbleView 是设置总背景图 //默认的时白色半透明(有点灰的感觉), UIBarStyleBlack,UIBarStyleBlackTranslucent ,UIBarS ...
随机推荐
- leetcode系列---atoiFunction C#code
Function: /// <summary> /// ToInt /// </summary> /// <param name="str">& ...
- js如何展示上传的图片
前言:本文章主要讲的是上传的图片如何展示在页面上. 一般来说,我们会先将本地图片上传到服务器,上传成功后,由后台返回图片的网络地址再在前端显示.但是,我今天讲的是不通过前面说的过程,而是直接使用js将 ...
- CentOS生产环境无网络安装percona-xtrabackup2.4【RPM安装教程】
Percona XtraBackup 8.0不支持对在MySQL 8.0之前的版本,Percona Server for MySQL或 Percona XtraDB Cluster中创建的数据库进行备 ...
- Web for pentester_writeup之Directory traversal篇
Web for pentester_writeup之Directory traversal篇 Directory traversal(目录遍历) 目录遍历漏洞,这部分有三个例子,直接查看源代码 Exa ...
- [考试反思]0803NOIP模拟测试12:偿还
嗯,rank5.没什么可评价的,高不算高低不算低. 一套好题,被我浪费了. 离上面280的大神差的有点远. 分机房的绝响就要来临. 越来越感觉自己变菜了,整体的能力水平在下滑. 说的不只是考试,包括平 ...
- CSPS模拟 57
rank4大众rank T1 天空龙 让他自由翱翔吧 T2 巨神兵 对于n=10的测试点本可以打出非常优秀的分层状压 但是没有打出来,因为对拓扑图理解不够深刻,纠结于指回的边,实际上只关注伸出的边就可 ...
- VirtualBox6安装CentOS7设置静态IP
安装virtualbox后安装centos7, 这里就不在赘述了, 网上有很多教程 先关闭虚拟机, 按照如下设置配置网络 这里需要使用双网卡, 我们在开启第二个网卡, 如下所示 之后开启虚拟机, 进行 ...
- 最新JetBrains PyCharm 使用教程--安装教程(一)
安装过程 Pycharm 激活码 license server选项里边输入:http://intellij.mandroid.cn/
- 46 Linden Street ACT I
Execute me. My name is Richard Stewart. I’m a photographer. May I take a picture of you and your lit ...
- C#同级catch块和finally块中全都抛出异常,上一级捕获哪一个?
C#同级catch块和finally块中全都抛出异常,上一级优先捕获finally块中的异常. 测试代码: using System; namespace test { class Program { ...