Swift - 使用网格(UICollectionView)的自定义布局实现复杂页面

来源:互联网 发布:app网站数据统计工具 编辑:程序博客网 时间:2024/05/25 19:55
网格UICollectionView除了使用流布局,还可以使用自定义布局。实现自定义布局需要继承UICollectionViewLayout,同时还要重载下面的三个方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
// 这个方法返回每个单元格的位置和大小
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath)
    -> UICollectionViewLayoutAttributes? {
}
  
// 返回内容区域总大小,不是可见区域
override func collectionViewContentSize() -> CGSize {
}
  
// 返回所有单元格位置属性
override func layoutAttributesForElementsInRect(rect: CGRect)
    -> [UICollectionViewLayoutAttributes]? {
}

下面实现一个自定义布局的例子,单元格有大小两种。网格从上到下,先是左边一个大单元格右边两个小单元格,接着左边两个小单元格右边一个大单元格,依次同上循环排列。 
效果图如下:
  
原文:Swift - 使用网格(UICollectionView)的自定义布局实现复杂页面


--- 自定义布局 CustomLayout.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
 
/**
 * 这个类只简单定义了一个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)
        -> [UICollectionViewLayoutAttributes]? {
        var attributesArray = [UICollectionViewLayoutAttributes]()
        let cellCount = self.collectionView!.numberOfItemsInSection(0)
        for in 0..<cellCount {
            let indexPath =  NSIndexPath(forItem:i, inSection:0)
             
            let attributes =  self.layoutAttributesForItemAtIndexPath(indexPath)
             
            attributesArray.append(attributes!)
             
        }
        return attributesArray
    }
     
    // 这个方法返回每个单元格的位置和大小
    override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath)
        -> UICollectionViewLayoutAttributes? {
        //当前单元格布局属性
        let attribute =  UICollectionViewLayoutAttributes(forCellWithIndexPath:indexPath)
         
        //单元格外部空隙,简单起见,这些常量都在方法内部定义了,没有共享为类成员
        //let itemSpacing = 2
        let lineSpacing = 5
         
        //单元格边长
        let largeCellSide:CGFloat = 200
        let smallCellSide:CGFloat = 100
         
        //内部间隙,左右5
        let insets = UIEdgeInsetsMake(2, 5, 2, 5)
         
        //当前行数,每行显示3个图片,1大2小
        let line:Int =  indexPath.item / 3
        //当前行的Y坐标
        let lineOriginY =  largeCellSide * CGFloat(line) + CGFloat(lineSpacing * line)
            + insets.top
        //右侧单元格X坐标,这里按左右对齐,所以中间空隙大
        let rightLargeX =  collectionView!.bounds.size.width - largeCellSide - insets.right
        let 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!
    */
}

--- 主页面 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
import UIKit
 
class ViewControllerUIViewControllerUICollectionViewDelegateUICollectionViewDataSource
{
     
    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()
         
        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()
    }
     
    // 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)
    }
    */
}

原文出自:www.hangge.com  转载请保留原文链接:http://www.hangge.com/blog/cache/detail_591.html
0 0
原创粉丝点击