钟情圆角怎么办


最近由于我们的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. [HNOI2004]L语言 trie树? Ac自动机? hash!!

    题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成.一个字典D是若干个单词的 ...

  2. GUI编程(Tkinter) 笔记分享

    Python GUI编程(Tkinter) Python 提供了多个图形开发界面的库,几个常用 Python GUI 库如下: Tkinter: Tkinter 模块(Tk 接口)是 Python 的 ...

  3. H5与CSS3常用设置

    1.设置div铺满全屏 对于一个div1,要使其属性height:100%生效,需要使其所有父元素,有确定的属性height.要铺满全屏,就是从html开始,所有的height为100%. 2.垂直居 ...

  4. SAP SOAMANAGER报错原因与故障排除方法

    一些刚刚接触到SAP Webservice的开发者由于对SAP Netweaver组件的不熟悉,往往在使用事物码SOAMANAGER进行webservice配置的时候,发现无法正常启动SOAMANAG ...

  5. 手写SpringMVC 框架

    手写SpringMVC框架 细嗅蔷薇 心有猛虎 背景:Spring 想必大家都听说过,可能现在更多流行的是Spring Boot 和Spring Cloud 框架:但是SpringMVC 作为一款实现 ...

  6. 路由传参 query 和 params

    vue路由传参分为两种情况: 一.query和params传参的区别: 1.query传参显示参数,params传参不显示参数,params相对于query来说较安全一点. 2.取值方法也有不同:qu ...

  7. 大数据之路day05_1--初识类、对象

    1.1 什么是面向对象        面向对象思想就是不断的创建对象(属性与行为的封装,让二者作为整体参与程序执行),使用对象,指挥对象做事情.(在已有对象的情况下,直接使用对象,而不再去考虑对象的内 ...

  8. 获取tomcat的deploy路径(用于存放用户上传的文件,如果不放在这会出现图片不能及时加载出来的问题!)

    String path =request.getSession().getServletContext().getRealPath("/“);

  9. Java I/O体系从原理到应用,这一篇全说清楚了

    本文介绍操作系统I/O工作原理,Java I/O设计,基本使用,开源项目中实现高性能I/O常见方法和实现,彻底搞懂高性能I/O之道 基础概念 在介绍I/O原理之前,先重温几个基础概念: (1) 操作系 ...

  10. linux 打包 | autoconf 使用方法

    面试题 嵌入式 0x10道题目 宏定义 #define 宏体 宏体 (大写) #define SECOND_OF_YEAR (365*24*3600)UL 可移植性 数据声明 一个存有10个指针的数组 ...