标签:
网格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) } */ } |
Swift - 使用网格(UICollectionView)的自定义布局实现复杂页面
标签:
原文地址:http://www.cnblogs.com/Free-Thinker/p/4838300.html