1
2
3
4
5
6
7
8
9
10
11
12
13
|
//
内容区域总大小,不是可见区域
override var collectionViewContentSize: CGSize {
}
//
所有单元格位置属性
override func layoutAttributesForElements( in rect: CGRect )
->
[ UICollectionViewLayoutAttributes ]?
{
}
//
这个方法返回每个单元格的位置和大小
override func layoutAttributesForItem(at
indexPath: IndexPath )
-> UICollectionViewLayoutAttributes ?
{
}
|
下面实现一个自定义布局的例子,单元格有大小两种。网格从上到下,先是左边一个大单元格右边两个小单元格,接着左边两个小单元格右边一个大单元格,依次同上循环排列。
效果图如下:
--- 自定义布局 CustomLayout.swift ---
(本文样例代码已升级到Swift3)
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 var collectionViewContentSize: CGSize {
let width
= collectionView!.bounds.size.width - collectionView!.contentInset.left
-
collectionView!.contentInset.right
let height
= CGFloat ((collectionView!.numberOfItems(inSection:
0) + 1) / 3)
*
(width / 3 * 2)
return CGSize (width:
width, height: height)
}
//
所有单元格位置属性
override func layoutAttributesForElements( in rect: CGRect )
->
[ UICollectionViewLayoutAttributes ]?
{
var attributesArray
= [ UICollectionViewLayoutAttributes ]()
let cellCount
= self .collectionView!.numberOfItems(inSection:
0)
for i in 0..<cellCount
{
let indexPath
= IndexPath (item:i,
section:0)
let attributes
= self .layoutAttributesForItem(at:
indexPath)
attributesArray.append(attributes!)
}
return attributesArray
}
//
这个方法返回每个单元格的位置和大小
override func layoutAttributesForItem(at
indexPath: IndexPath )
-> UICollectionViewLayoutAttributes ?
{
//当前单元格布局属性
let attribute
= UICollectionViewLayoutAttributes (forCellWith:indexPath)
//单元格边长
let largeCellSide
= collectionViewContentSize.width / 3 * 2
let smallCellSide
= collectionViewContentSize.width / 3
//当前行数,每行显示3个图片,1大2小
let line: Int =
indexPath.item / 3
//当前行的Y坐标
let lineOriginY
= largeCellSide * CGFloat (line)
//右侧单元格X坐标,这里按左右对齐,所以中间空隙大
let rightLargeX
= collectionViewContentSize.width - largeCellSide
let rightSmallX
= collectionViewContentSize.width - smallCellSide
//
每行2个图片,2行循环一次,一共6种位置
if (indexPath.item
% 6 == 0) {
attribute.frame
= CGRect (x:0,
y:lineOriginY, width:largeCellSide,
height:largeCellSide)
} else if (indexPath.item
% 6 == 1) {
attribute.frame
= CGRect (x:rightSmallX,
y:lineOriginY, width:smallCellSide,
height:smallCellSide)
} else if (indexPath.item
% 6 == 2) {
attribute.frame
= CGRect (x:rightSmallX,
y:lineOriginY
+ smallCellSide,
width:smallCellSide,
height:smallCellSide)
} else if (indexPath.item
% 6 == 3) {
attribute.frame
= CGRect (x:0,
y:lineOriginY, width:smallCellSide,
height:smallCellSide
)
} else if (indexPath.item
% 6 == 4) {
attribute.frame
= CGRect (x:0,
y:lineOriginY
+ smallCellSide,
width:smallCellSide,
height:smallCellSide)
} else if (indexPath.item
% 6 == 5) {
attribute.frame
= CGRect (x:rightLargeX,
y:lineOriginY,
width:largeCellSide,
height:largeCellSide)
}
return attribute
}
/*
//如果有页眉、页脚或者背景,可以用下面的方法实现更多效果
func
layoutAttributesForSupplementaryViewOfKind(elementKind: String!,
atIndexPath
indexPath: NSIndexPath!) -> UICollectionViewLayoutAttributes!
func
layoutAttributesForDecorationViewOfKind(elementKind: String!,
atIndexPath
indexPath: NSIndexPath!) -> UICollectionViewLayoutAttributes!
*/
}
|
--- 主页面 ViewController.swift ---
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
83
84
85
86
87
|
import UIKit
class ViewController : UIViewController , UICollectionViewDelegate , UICollectionViewDataSource
{
var collectionView: UICollectionView !
//课程名称和图片,每一门课程用字典来表示
let courses
= [
[ "name" : "Swift" , "pic" : "swift.png" ],
[ "name" : "Xcode" , "pic" : "xcode.png" ],
[ "name" : "Java" , "pic" : "java.png" ],
[ "name" : "PHP" , "pic" : "php.png" ],
[ "name" : "JS" , "pic" : "js.png" ],
[ "name" : "React" , "pic" : "react.png" ],
[ "name" : "Ruby" , "pic" : "ruby.png" ],
[ "name" : "HTML" , "pic" : "html.png" ],
[ "name" : "C#" , "pic" : "c#.png" ]
]
override func viewDidLoad()
{
super .viewDidLoad()
let layout
= CustomLayout ()
//let
layout = UICollectionViewFlowLayout()
let frame
= CGRect (x:0,
y:20, width: view.bounds.size.width,
height:view.bounds.height-20)
self .collectionView
= UICollectionView (frame:
frame, collectionViewLayout:layout)
self .collectionView.delegate
= self
self .collectionView.dataSource
= self
//
注册CollectionViewCell
self .collectionView.register( UICollectionViewCell . self ,
forCellWithReuseIdentifier: "ViewCell" )
//默认背景是黑色和label一致
self .collectionView.backgroundColor
= UIColor .white
//设置collectionView的内边距
self .collectionView.contentInset
= UIEdgeInsetsMake (0,
5, 0, 5)
self .view.addSubview(collectionView)
}
override func didReceiveMemoryWarning()
{
super .didReceiveMemoryWarning()
}
//
CollectionView行数
func collectionView(_
collectionView: UICollectionView ,
numberOfItemsInSection
section: Int )
-> Int {
return courses.count;
}
//
获取单元格
func collectionView(_
collectionView: UICollectionView ,
cellForItemAt
indexPath: IndexPath )
-> UICollectionViewCell {
//
storyboard里设计的单元格
let identify: String = "ViewCell"
//
获取设计的单元格,不需要再动态添加界面元素
let cell
= self .collectionView.dequeueReusableCell(
withReuseIdentifier:
identify, for :
indexPath) as UICollectionViewCell
//先清空内部原有的元素
for subview in cell.subviews
{
subview.removeFromSuperview()
}
//
添加图片
let img
= UIImageView (image: UIImage (named:
courses[indexPath.item][ "pic" ]!))
img.frame
= cell.bounds
img.contentMode
= .scaleAspectFit
//
图片上面显示课程名称,居中显示
let lbl
= UILabel (frame: CGRect (x:0,
y:0, width:cell.bounds.size.width, height:20))
lbl.textColor
= UIColor .white
lbl.textAlignment
= .center
lbl.backgroundColor
= UIColor (red:
0, green: 0, blue: 0, alpha: 0.2)
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)
}
*/
}
|