钟情圆角怎么办


最近由于我们的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设置组背景和圆角的更多相关文章

  1. Android给TextView设置透明背景、圆角边框

    第一种方法:在drawable文件夹下新建一个文件设置背景样式 代码: 在drawable文件夹下面新建text_view_border.xml <?xml version="1.0& ...

  2. Swift开发教程--设置UIViewController的背景透明

    非常easy的一句代码 self.view.backgroundColor = UIColor.clearColor() 由此联想开来,非常多的控件想设置为背景透明都能够用UIColor.clearC ...

  3. Qt 之 设置窗口边框的圆角(使用QSS和PaintEvent两种方法)

    Qt在设置窗口边框圆角时有两种方式,一种是设置样式,另一种是在paintEvent事件中绘制窗口.下面分别叙述用这两种方式来实现窗口边框圆角的效果. 一.使用setStyleSheet方法 this- ...

  4. 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 ...

  5. APUE学习之三个特殊位 设置用户ID(set-user-ID),设置组ID(set-group-ID),sticky

    设置用户ID(set-user-ID),设置组ID(set-group-ID),sticky   set-user-ID: SUID      当文件的该位有设置时,表示当该文件被执行时,程序具有文件 ...

  6. 【转】linux 设置用户id 设置组id

    linux 设置用户id 设置组id   转自 linux 设置用户id 设置组id   最近看apue,简单记录对设置用户id理解(设置组id同理). 1. 相关的id好像很多,共有哪些? 文件2个 ...

  7. Windows 7个性化配置,关闭Win7动画效果,设置窗口背景为“ 豆绿色”

    减少眼睛疲劳配色(豆绿色): RGB:, , ,颜色名称:#C7EDCC 1.任务栏设置 2.关闭Win7动画效果 控制面板 -> 轻松访问 -> 优化视频显示 3.去掉窗口阴影 右键单击 ...

  8. 在IE6下使用filter设置png背景

    今天帮别人解决问题学会了一个在IE6下使用filter设置png背景,具体css写法如下: .login_form_wrap { width: 778px; height: 360px; backgr ...

  9. 导航栏视图设置 tabbleView 是设置总背景图

    //导航栏视图设置 tabbleView 是设置总背景图 //默认的时白色半透明(有点灰的感觉), UIBarStyleBlack,UIBarStyleBlackTranslucent ,UIBarS ...

随机推荐

  1. ArcGIS Engine添加地图元素的实现

    在ArcGIS中,我们使用的制图控件除了MapControl之外,还有PageLayoutControl,用于页面布局和制图,生成一幅成品地图. PageLayoutControl 封装了PageLa ...

  2. mysql免安装包配置

    最近在通过zip包配置mysql,mysql版本:5.7.13.配置过程中,踩了一些坑,下面做了一些简单的记录,配置的具体过程如下: 1.将mysql zip包解压,放到指定目录中,在系统环境变量中配 ...

  3. Life is short, I love Python~!

    python学习目录 一:计算机基础 计算机基础 二:python基础 python基础 三:函数 函数 内置函数匿名函数 迭代器生成器 四:文件处理&异常 文件处理 异常处理 五:模块 常用 ...

  4. Python enumerate() 函数笔记

    enumerate函数说明: 函数原型:enumerate(sequence, [start=0])  #第二个参数为指定索引 功能:将可循环序列sequence以start开始分别列出序列数据和数据 ...

  5. JDK JRE JVM的区别与关系

    JDK JAVA开发工具包    他包含了JRE   JAVA运行环境   JVM JAVA虚拟机他是跨平台的核心主件   他将Java源文件编译成 .class结尾字节码文件交由不同计算机执行    ...

  6. spring boot跨域请求访问配置以及spring security中配置失效的原理解析

    一.同源策略 同源策略[same origin policy]是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源. 同源策略是浏览器安全的基石. 什么是源 源[orig ...

  7. csps模拟测试 77爆零反思

    题不算太难,可是我还是没考出应有水平. $1h8min$切掉前两道题,然后$T3$想到正解并且码出来了并且过了大样例并且爆零. 没什么好说的,我太自信了,没打对拍? 想到了正解,还不如随便打个暴力分高 ...

  8. VM 使用问题 | 安装失败->>注册表

    下午乌龙了一回,本来就知道注册表都卸载的乱乱的 以为安装上即可,越弄越糊涂 无法安装.... 查了注册表,发现那些都删除了 手动安装实在太过麻烦,弄了一早上. 如图:未能解决 ​ ​ ​ 后使用了清洁 ...

  9. 深入理解计算机系统 第二章 信息的表示和处理 part2

      上一周遗留问题的解决 问题:原码.反码.补码是只针对有符号数吗?无符号数有没有这三种编码方式? 得到的答案:对于无符号数,原码.反码和补码是一致的 进一步,由于有符号数是以补码的形式存储在计算机中 ...

  10. 安装&卸载Windows服务

    使用.NET Framework的工具InstallUtil.exe. 安装服务 C:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.e ...