钟情圆角怎么办


最近由于我们的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. sql 经典查询50题 思路(一)

    因为需要提高一下sql的查询能力,当然最快的方式就是做一些实际的题目了.选择了这个sql的50题,这次大概做了前10题左右,把思路放上来,也是一个总结. 具体题目见: https://zhuanlan ...

  2. MySql逻辑结构简介

    结构示意图: 如上图,可把数据库的结构分成四层,见下图及文字说明  一.连接层提供客户端和连接服务,包含本地Sock通信和大多数基于客户端/服务端工具实现的类似于TCP/IP的通信,主要完成一些类似于 ...

  3. phpStorm //todo 的用途

    用phpstorm看到别人的代码使用了注释//todo,且todo是彩色的 我想这个应该是有点用的吧,于是百度了下,大概是可能由于某些原因,导致部分代码没有写.但又怕忘了, 用//todo就可以做提示 ...

  4. Kali Linux——迈向网络攻防

    自从进入大三的课程后,在已学的高数.线代.数论.概率论.信息论.通信等知识的技术上,开始了网络信息安全.网      络攻防的学习.俗话说得好,磨刀不误砍柴工,开始网络攻防之旅也势必要一个好的工具.然 ...

  5. windows上使用VsCode开发C/C++

    使用VsCode+makefile开发C/C++ 1. 介绍 vscode作为现在越来越受欢迎的编辑器之一,因为可以使用插件让vscode支持几乎市面上所有的编程语言,由于笔者主要接触的是 C/C++ ...

  6. [考试反思]0821NOIP模拟测试28:沉默

    这次不能把我前面的分数段都列出来了,因为实在太多了. 这次也不能把我后面的分数段列出来了,因为我后面没有了. yxm,mikufun,Pairs170100分第10.50分第29. 我:爆零,倒数第一 ...

  7. NOIP模拟测试6

    看题目就知道这是一个悲伤的故事... 但还有更悲伤的 考崩了,难以描述. T1把数据范围看成2^12,我TM也是够了... T2思路接近正解,但不知道想了个神魔东西跑了N遍dijstra T3最狗了, ...

  8. day 2 DP专场

    上午讲了一上午背包,从01背包到完全背包到多重背包,感觉也没说什么,旁边的大佬一直在飞鸽里说让老师讲快点,然而最后也没人敢跟老师说.... 例题真的各个都是神仙题, 挂饰 好像就是一上午最简单的... ...

  9. 虚拟机操作系统内设置固定IP以及克隆虚拟机

    以下为我自己整理的克隆虚拟机和设置固定IP的方法,记录一下,以防忘记: 桥接模式网络配置 1.配置ip地址等信息在/etc/sysconfig/network-scripts/ifcfg-ens33文 ...

  10. Jenkins发送测试报告

    邮件全局配置 邮件插件:Email Extension Plugin 功能:发送邮件 邮件全局配置:jenkins--系统管理--系统配置:截图: 配置说明: 系统管理员邮件地址:必须配置,配置后邮件 ...