Swift - 使用网格(UICollectionView)的自定义布局实现复杂页面
网格UICollectionView除了使用流布局,还可以使用自定义布局。实现自定义布局需要继承UICollectionViewLayout,同时还要重载下面的三个方法:
1
2
3
4
5
6
7
8
9
10
11
12
|
// 这个方法返回每个单元格的位置和大小
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath )
-> UICollectionViewLayoutAttributes ! {
}
// 返回内容区域总大小,不是可见区域
override func collectionViewContentSize() -> CGSize {
}
// 返回所有单元格位置属性
override func layoutAttributesForElementsInRect(rect: CGRect ) -> [ AnyObject ] {
}
|
下面实现一个自定义布局的例子,单元格有大小两种。网格从上到下,先是左边一个大单元格右边两个小单元格,接着左边两个小单元格右边一个大单元格,依次同上循环排列。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
import UIKit
/**
* 这个类只简单定义了一个section的布局
*/
class CustomLayout : UICollectionViewLayout {
// 内容区域总大小,不是可见区域
override func collectionViewContentSize() -> CGSize {
return CGSizeMake (collectionView!.bounds.size.width,
CGFloat (collectionView!.numberOfItemsInSection(0) * 200 / 3 + 200))
}
// 所有单元格位置属性
override func layoutAttributesForElementsInRect(rect: CGRect ) -> [ AnyObject ] {
var attributesArray = [ AnyObject ]()
let cellCount = self .collectionView!.numberOfItemsInSection(0)
for i in 0..<cellCount {
var indexPath = NSIndexPath (forItem:i, inSection:0)
var attributes = self .layoutAttributesForItemAtIndexPath(indexPath)
attributesArray.append(attributes)
}
return attributesArray
}
// 这个方法返回每个单元格的位置和大小
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath )
-> UICollectionViewLayoutAttributes ! {
//当前单元格布局属性
var attribute = UICollectionViewLayoutAttributes (forCellWithIndexPath:indexPath)
//单元格外部空隙,简单起见,这些常量都在方法内部定义了,没有共享为类成员
let itemSpacing = 2
let lineSpacing = 5
//单元格边长
let largeCellSide: CGFloat = 200
let smallCellSide: CGFloat = 100
//内部间隙,左右5
var insets = UIEdgeInsetsMake (2, 5, 2, 5)
//当前行数,每行显示3个图片,1大2小
var line: Int = indexPath.item / 3
//当前行的Y坐标
var lineOriginY = largeCellSide * CGFloat (line) + CGFloat (lineSpacing * line) + insets.top
//右侧单元格X坐标,这里按左右对齐,所以中间空隙大
var rightLargeX = collectionView!.bounds.size.width - largeCellSide - insets.right
var rightSmallX = collectionView!.bounds.size.width - smallCellSide - insets.right
// 每行2个图片,2行循环一次,一共6种位置
if (indexPath.item % 6 == 0) {
attribute.frame = CGRectMake (insets.left, lineOriginY, largeCellSide, largeCellSide)
} else if (indexPath.item % 6 == 1) {
attribute.frame = CGRectMake (rightSmallX, lineOriginY, smallCellSide, smallCellSide)
} else if (indexPath.item % 6 == 2) {
attribute.frame = CGRectMake (rightSmallX, lineOriginY + smallCellSide + insets.top,
smallCellSide, smallCellSide)
} else if (indexPath.item % 6 == 3) {
attribute.frame = CGRectMake (insets.left, lineOriginY, smallCellSide, smallCellSide)
} else if (indexPath.item % 6 == 4) {
attribute.frame = CGRectMake (insets.left, lineOriginY + smallCellSide + insets.top,
smallCellSide, smallCellSide)
} else if (indexPath.item % 6 == 5) {
attribute.frame = CGRectMake (rightLargeX, lineOriginY, largeCellSide, largeCellSide)
}
return attribute
}
/*
//如果有页眉、页脚或者背景,可以用下面的方法实现更多效果
func layoutAttributesForSupplementaryViewOfKind(elementKind: String!,
atIndexPath indexPath: NSIndexPath!) -> UICollectionViewLayoutAttributes!
func layoutAttributesForDecorationViewOfKind(elementKind: String!,
atIndexPath indexPath: NSIndexPath!) -> UICollectionViewLayoutAttributes!
*/
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
import UIKit
class ViewController : UIViewController , UICollectionViewDelegate , UICollectionViewDataSource
{
var collectionView: UICollectionView !
//课程名称和图片,每一门课程用字典来表示
let courses = [
[ "name" : "Swift" , "pic" : "swift.png" ],
[ "name" : "OC" , "pic" : "oc.jpg" ],
[ "name" : "Java" , "pic" : "java.png" ],
[ "name" : "PHP" , "pic" : "php.jpeg" ],
[ "name" : "JS" , "pic" : "js.jpeg" ],
[ "name" : "HTML" , "pic" : "html.jpeg" ],
[ "name" : "Ruby" , "pic" : "ruby.png" ]
]
override func viewDidLoad() {
super .viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let layout = CustomLayout ()
//let layout = UICollectionViewFlowLayout()
self .collectionView = UICollectionView (
frame: CGRectMake (0,20,view.bounds.size.width,view.bounds.height-20),
collectionViewLayout:layout)
self .collectionView.delegate = self
self .collectionView.dataSource = self
// 注册CollectionViewCell
self .collectionView.registerClass( UICollectionViewCell . self ,
forCellWithReuseIdentifier: "ViewCell" )
//默认背景是黑色和label一致
self .collectionView.backgroundColor = UIColor .whiteColor()
self .view.addSubview(collectionView)
}
override func didReceiveMemoryWarning() {
super .didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// CollectionView行数
func collectionView(collectionView: UICollectionView , numberOfItemsInSection section: Int ) -> Int {
return courses.count;
}
// 获取单元格
func collectionView(collectionView: UICollectionView , cellForItemAtIndexPath indexPath: NSIndexPath )
-> UICollectionViewCell {
// storyboard里设计的单元格
let identify: String = "ViewCell"
// 获取设计的单元格,不需要再动态添加界面元素
let cell = self .collectionView.dequeueReusableCellWithReuseIdentifier(
identify, forIndexPath: indexPath) as UICollectionViewCell
// 添加图片
let img = UIImageView (image: UIImage (named: courses[indexPath.item][ "pic" ]!))
img.frame = cell.bounds
// 图片上面显示课程名称,居中显示
let lbl = UILabel (frame: CGRectMake (0,5,cell.bounds.size.width,20))
lbl.textAlignment = NSTextAlignment . Center
lbl.text = courses[indexPath.item][ "name" ]
cell.addSubview(img)
cell.addSubview(lbl)
return cell
}
/* 自定义布局不需要调用
//单元格大小
func collectionView(collectionView: UICollectionView!,
layout collectionViewLayout: UICollectionViewLayout!,
sizeForItemAtIndexPath indexPath: NSIndexPath!) -> CGSize {
let size:Float = indexPath.item % 3 == 0 ? 200 : 100
return CGSize(width:size, height:size)
}
*/
}
|
转载于:https://www.cnblogs.com/Free-Thinker/p/4838300.html
Swift - 使用网格(UICollectionView)的自定义布局实现复杂页面相关推荐
- iOS开发学无止境 - UICollectionView自定义布局之风火轮[译]
现在有许多极具创造力的网站,几周前我碰巧浏览到一个名为Form Follows Function的网站,上面有各种交互动画.其中最吸引我的是网站上的导航转轮,转轮由各种交互体验海报组成. 原文:UIC ...
- UICollectionView自定义布局(二)
这是UICollectionView自定义布局的第二篇,实现类似UltravisualApp的视差效果,同样这篇文章的教程来自Ray家的Swift Expanding Cells in iOS Col ...
- UICollectionView 自定义布局!看这篇就够了
各位同学早上好,新的一周又开始啦!眨眼之间,我们就要与3月挥手告别了,时间过得可真快,不禁感慨道"无可奈何花落去,似曾相识燕归来". 最近,我花了很多的时间整理了 UICollec ...
- UICollectionView 自定义布局教程: Pinterest
原文: UICollectionView Custom Layout Tutorial: Pinterest 作者:Paride Broggi 译者:kmyhy 更新说明:本教程由 Paride Br ...
- iOS-UICollectionView自定义布局
UICollectionView自定义布局 转载: http://answerhuang.duapp.com/index.php/2013/11/20/custom_collection_view_l ...
- 自定义布局和自定义流水布局(CollectionViewLayout和CollectionViewFlowLayout)实例
自定义布局和自定义流水布局(CollectionViewLayout和CollectionViewFlowLayout) 转载:https://www.jianshu.com/p/83f2d6ac7e ...
- ViewGroup1——自定义布局
平时开发时,系统提供的几个布局基本就能满足我们的需求了.如果系统提供的布局无法满足需求,我们可以扩展ViewGroup类来实现自定义布局控件.先看下ViewGroup的继承图 由上图可知,ViewGr ...
- 从自定义TagLayout看自定义布局的一般步骤[手动加精]
从自定义TagLayout看自定义布局的一般步骤[手动加精] 我们常用的布局有LinearLayout,FrameLayout,RelativeLayout,大多数情况下都能满足我们的需求,但是也有很 ...
- 【Android 性能优化】布局渲染优化 ( 过渡绘制 | 背景设置产生的过度绘制 | Android 系统的渲染优化 | 自定义布局渲染优化 )
文章目录 一. 背景设置产生的过度绘制 二. Android 系统的渲染优化 1. 透明组件数据传递 2. GPU 存储机制 3. Android 7.0 之后的优化机制 三. 自定义布局渲染优化 一 ...
最新文章
- 计图MPI分布式多卡
- ImportError:cannot import name ‘display‘ File “XX“, line 5, in <module> from IPython import display
- Visual Studio 2019 16.1 第二个预览版发布
- c语言是非结构化程序设计语言,第章_结构化程序设计基础和C语言的控制结构(fb).ppt...
- python_day9线程、进程和协程
- ML之DL:机器学习领域发展最快的分支【深度学习】的发展史及其重要性节点之详细攻略
- MySQL 随笔记录
- 将MSRA-TD500标签转换成逆时针输出标签+labeleme json格式转四个点的txt
- 【实践】多场景下的搜索词推荐算法及在腾讯的应用实践.pdf(附下载链接)
- Android Error:Could not find lottie.jar
- 我的java web之路(安装)
- android m版本 root,Android M或开放更多权限,root还需要吗?
- 数据持久层框架Mybatis
- 各地级市-国内及外汇旅游收入(1995-2020)
- 再也不用花一天时间做ppt了
- war3 魔兽争霸3 双开 多开 联机 补丁 工具
- 轻量级pdf查看阅读工具Sumatra PDF
- 计算机word窗口的组成,word文件的组成
- [源码和报告分享]基于C++实现的运动会统分系统
- 数字图像处理大作业GUI设计