当前位置: > > > Swift - 使用网格(UICollectionView)进行流布局

Swift - 使用网格(UICollectionView)进行流布局

(本文代码已升级至Swift4)

一、网格UICollectionView最典型的例子是iBooks。其主要属性如下:

1,layout
该属性表示布局方式,有Flow、Custom两种布局方式。默认是Flow流式布局。

2,Accessories
是否显示页眉和页脚

3,各种尺寸属性
Cell Size:单元格尺寸
Header Size:页眉尺寸
Footer Size:页脚尺寸
Min Spacing:单元格之间间距
Section Insets:格分区上下左右空白区域大小。

二、流布局的简单样例

1,先创建一个应用Simple View Application,在 StoryBoard 中删除默认的 View Controller,拖入一个 Collection View Controller 到界面上,这时我们可以看到已经同时添加了 Collection View 和 Collection View Cell 控件。

2,勾选 Collection View Controller 属性面板里的 Is Initial View Controller 复选框,设置为启动视图控制器。

3,在 Collection View Cell里拖入一个Image View和Label并摆放好位置和大小,用于显示图标和名称。

4,设置Image View的tag为1,Label的tag为2,Colletion View Cell的Identifier为DesignViewCell。

5,最后,将 Collection View Controller 的 Custom Class 设置成 ViewController(ViewController.swift 里面代码可以先改,具体见下方)

效果图如下:
 
--- ViewController.swift ---
import UIKit

class ViewController: UICollectionViewController {
    
    //课程名称和图片,每一门课程用字典来表示
    let courses = [
        ["name":"Swift","pic":"swift.png"],
        ["name":"OC","pic":"oc.jpg"],
        ["name":"java","pic":"java.png"],
        ["name":"php","pic":"php.jpeg"]
    ]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 已经在界面上设计了Cell并定义了identity,不需要注册CollectionViewCell
        //self.collectionView.registerClass(UICollectionViewCell.self,
        //  forCellWithReuseIdentifier: "DesignViewCell")
        
        self.collectionView?.backgroundColor = UIColor.white
    }
    
    // CollectionView行数
    override func collectionView(_ collectionView: UICollectionView,
                                 numberOfItemsInSection section: Int) -> Int {
        return courses.count;
    }
    
    // 获取单元格
    override func collectionView(_ collectionView: UICollectionView,
                cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        // storyboard里设计的单元格
        let identify:String = "DesignViewCell"
        // 获取设计的单元格,不需要再动态添加界面元素
        let cell = (self.collectionView?.dequeueReusableCell(
            withReuseIdentifier: identify, for: indexPath))! as UICollectionViewCell
        // 从界面查找到控件元素并设置属性
        (cell.contentView.viewWithTag(1) as! UIImageView).image =
            UIImage(named: courses[indexPath.item]["pic"]!)
        (cell.contentView.viewWithTag(2) as! UILabel).text =
            courses[indexPath.item]["name"]
        return cell
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}


源码下载:hangge_ CollectionView.zip
评论(12)
  • 12楼
    2018-10-22 18:28
    zorroc

    按照示例,不显示图片和内容。

    站长回复:

    你肯定是哪一步错误了,再仔细检查下。我这边也把样例项目上传了,你可以比较下。

  • 11楼
    2017-06-05 14:27
    神天风翔

    航哥,怎么不用代码写,都用xib拖呢

    站长回复:

    用StoryBoard能很好的做到代码与视图分离,方便维护。让代码更关注业务逻辑,而不会掺杂有很多布局相关的操作在里面。

    这个还是看个人喜好,使用纯代码、不使用纯代码我其实都有写过相关的文章。选择适合自己的方式就好。

  • 10楼
    2017-04-21 15:38
    神风天翔

    override 报错,删掉override就不会运行这些代码,结果不论怎么一个字的代码都运行不了

    站长回复:

    你确定继承的是UICollectionViewController吗?

  • 9楼
    2017-04-21 15:23
    神风天翔

    怎么弄出来只有背景颜色显示出来了,一个单元格也没有

    站长回复:

    我测试了下是没问题的啊?你检查下是不是严格按照文章的12345步骤来,不要有遗漏了。

  • 8楼
    2017-01-11 10:09
    布袋

    collectionView设置成水平scroll时,怎么只显示一行呢?

    站长回复:

    把itemSize的高度设置成collectionVIew的高度一样就可以了。

  • 7楼
    2016-12-13 13:05
    xxx

    放上源文件岂不妙哉

    站长回复:

    这个样例很简单,就一个源文件(我已将代码放在页面上了)。照着步骤,我想你肯定能实现的。

  • 6楼
    2016-11-16 16:05
    eric

    为什么有的时候要问号,有的时候要感叹号呢?什么情况下用?,什么情况下用!。可以解释一下吗?

    站长回复:

    可选类型表示一个变量有可能有值,也可能没有值(nil)。
    如果你确定这个可选类型变量肯定有值时,可以用!。如果不确定是否有值就用?。否则如果是nil的话就会报错。

  • 5楼
    2016-07-20 11:32
    kid

    我按照您的步骤,结果怎么出来是黑屏呢?

    站长回复:

    应该是少了第5步。没有把 Collection View Controller 同 ViewController类关联起来。我更新了下文章,新增了几个图片,你可已再看下。

  • 4楼
    2016-06-28 17:09
    Alleluia

    航哥我想请问下,这里要怎么设置网络上的图片链接?

    // 从界面查找到控件元素并设置属性
    (cell.contentView.viewWithTag(1) as! UIImageView).image =
    UIImage(named: courses[indexPath.item]["pic"]!)

    站长回复:

    参考我原来写的这篇文章里的第4点:Swift - 图像控件(UIImageView)的用法

  • 3楼
    2016-04-06 10:22
    falcon_dl

    let identify = "menu_cell"
    let cell = menusCollection.dequeueReusableCellWithReuseIdentifier(identify, forIndexPath: indexPath) as UICollectionViewCell

    (cell.contentView.viewWithTag(10001) as! UIImageView).image = UIImage(named: "menu_2")
    好像没有通过tag取到图片对象

    站长回复:

    这个我也不太清楚了,如果tag设置正确的话都会取得到的。

  • 2楼
    2016-03-29 18:09
    Gavin

    您好,为什么我的self没有成员变量 collectionView,想从storyboard中用outlet连接也连接不了呢

    站长回复:

    self确定是UICollectionViewController吗?

  • 1楼
    2016-01-14 16:24
    蒂萨

    你不注册能出来 醉了

    站长回复:

    在StoryBoard中已经注册了(第4步),在代码里就不用再注册。有问题?