很多时候我们需要列表和宫格视图的来回切换,就像苹果的天气应用一样,我之前见过一个用tableview和collectionview来实现这种效果的,我本人不太喜欢这个,那么有没有更好的方法呢?答案是:有

初识UICollectionView

UICollectionView是一个比UITableView更灵活强大的控件。其他怎么使用这个控件这里不讲述,这里只说列表和宫格的切换。我们查看UICollectionView的API,可以发现有这么一个方法:

open func setCollectionViewLayout(_ layout: UICollectionViewLayout, animated: Bool) // transition from one layout to another

他的解释是转换一个布局到另一个布局。这不就是我们想要的嘛,我们实现两个布局,通过该方法,来回切换布局就行了。

接下来我们通过代码来实现

我们创建一个工程,命名为ListAndGrid,我们直接在默认创建的ViewController中先写这么几个属性

var collectionView: UICollectionView!
var datas: [String] {
var d = [String]()
for i in ... {
d.append("\(i)")
}
return d
}

let listLayout = UICollectionViewFlowLayout() // 列表布局

let gridLayout = UICollectionViewFlowLayout() // 宫格布局

接下来我们在viewDidLoad方法中对这几个属性进行初始设置

代码如下

override func viewDidLoad() {
super.viewDidLoad() listLayout.itemSize = CGSize(width: UIScreen.main.bounds.size.width, height: ) gridLayout.itemSize = CGSize(width: (UIScreen.main.bounds.size.width - ) / 3.0, height: )
gridLayout.minimumLineSpacing =
gridLayout.minimumInteritemSpacing = collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: listLayout)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(UINib.init(nibName: "LabelCell", bundle: nil), forCellWithReuseIdentifier: "LabelCell") collectionView.backgroundColor = UIColor.white
view.addSubview(collectionView)
// Do any additional setup after loading the view, typically from a nib. }

然后实现UICollectionView相应的代理方法

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return datas.count
} func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "LabelCell", for: indexPath) as! LabelCell
cell.label.text = datas[indexPath.row]
return cell
}

至此我们已经实现所有基本代码,接下来我们需要触发setCollectionViewLayout这个方法,我这里是在导航控制器上添加了一个item,这里给出触发事件的代码

@IBAction func clickItem(_ sender: UIBarButtonItem) {
if collectionView.collectionViewLayout == listLayout {
collectionView.setCollectionViewLayout(gridLayout, animated: true)
} else {
collectionView.setCollectionViewLayout(listLayout, animated: true)
}
}

运行程序,效果如下图

切换之后改变cell样式

这是cell样式一样的情况,如果我们要在不用的布局中用不同的cell样式该怎么办呢?

我们首先要在viewDidLoad中添加另一个cell的注册代码,以便复用

collectionView.register(UINib.init(nibName: "LabelCell2", bundle: nil), forCellWithReuseIdentifier: "LabelCell2")

然后func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell代理中也需要做一些改变,我们需要区分是哪种布局,改为下面这样

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView.collectionViewLayout == listLayout {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "LabelCell", for: indexPath) as! LabelCell
cell.label.text = datas[indexPath.row]
return cell
} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "LabelCell2", for: indexPath) as! LabelCell2
cell.label.text = datas[indexPath.row]
return cell
}
}

最后关键的地方来了,我们如果用之前的切换布局方法会发现根本达不到目的,我们查看API发现有一个类似的方法是:func setCollectionViewLayout(_ layout: UICollectionViewLayout, animated: Bool, completion: ((Bool) -> Swift.Void)? = nil),这个方法比之前那个多一个完成之后的回调,我们可以利用回调来重新加载一下数据就可以了,这次触发时间里的代码如下:

@IBAction func clickItem(_ sender: UIBarButtonItem) {
if collectionView.collectionViewLayout == listLayout {
collectionView.setCollectionViewLayout(gridLayout, animated: true, completion: { (com) in
if com {
self.collectionView.reloadData()
}
}) } else {
collectionView.setCollectionViewLayout(listLayout, animated: true, completion: { (com) in
if com {
self.collectionView.reloadData()
}
}) }
}

我们是在布局切换完之后又重新刷了一下数据。

运行程序,效果如下

至此,基本的内容已经讲解完,通过这些我们可以完成更复杂的内容

本工程代码请点击下载

利用UICollectionView实现列表和宫格视图的切换的更多相关文章

  1. SharePoint开发 - Excel数据导入到SharePoint自定义列表(数据视图方式)

    博客地址 http://blog.csdn.net/foxdave 本篇讲解一个有些新颖的SharePoint实例应用,给甲方做过项目的都有过体会,数据太多了,客户有Excel,要求实现批量导入. 效 ...

  2. python利用or在列表解析中调用多个函数.py

    python利用or在列表解析中调用多个函数.py """ python利用or在列表解析中调用多个函数.py 2016年3月15日 05:08:42 codegay & ...

  3. [改善Java代码]子列表只是原列表的一个视图

    List接口提供了subList方法,其作用是返回一个列表的子列表.这与String类的subString有点类似.但是他们的功能是否相同?看代码: import java.util.ArrayLis ...

  4. 利用UICollectionView实现瀑布流

    利用UICollectionView实现瀑布流通过自定义布局来实现. - 自定义类继承UICollectionViewLayout: 必须重写的方法有: //决定每个item的位置: - (nulla ...

  5. Jenkins 利用Dashboard View插件管理任务视图

    利用Dashboard View插件管理任务视图   by:授客 QQ:1033553122 步骤 1.  安装Dashboard View插件 说明: 如果无法在线安装,可以选择本地上传方式安装 附 ...

  6. iOS - UICollectionView 瀑布流 添加表头视图的坑

    UICollectionView 瀑布流 添加表头视图的坑 首先是,需求加了个头视图在顶部,在collectionView中的头视图跟TableView的不一样,TableView的表头只要设置tab ...

  7. python3之利用字典和列表实现城市多级菜单

    利用字典和列表实现城市多级菜单 #coding:utf-8 #利用字典和列表实现城市多级菜单 addrIndex = {":"福建"} addrDict = {" ...

  8. C利用可变参数列表统计一组数的平均值,利用函数形式参数栈原理实现指针运算

    //描述:利用可变参数列表统计一组数的平均值 #include <stdarg.h> #include <stdio.h> float average(int num, ... ...

  9. 【逆向工具】IDA使用5-( string、图形化与视图的切换、图形化显示反汇编地址、自动注释、标签使用)

    分析petya病毒时新学会的技巧. IDA技巧1 : string 提取文件中的字符串内容,如果看到一些文件字符串可以定位到关键的函数中. view -> open subview -> ...

随机推荐

  1. 教你搭建你自己的Git服务器

    http://lib.csdn.net/article/git/50086 导读 现在我们将要学习如何搭建 git 服务器,如何编写自定义的 Git 钩子来在特定的事件触发相应的动作(例如通知),或者 ...

  2. 关于富文本在Android中的应用以及遇到的坑

    富文本可以为用户提供更加多样化的文本展示形式,但由于其使用了H5标签的特殊性,一般都需要第三方框架的支持.这里推荐一款合适的第三方富文本框架,richeditor. 首先我们要使用该功能需要引入相关j ...

  3. flask_route错误:AttributeError: 'function' object has no attribute 'route'

    问题: 路由完全正确,当只有一个名为home的函数处理这个路由时候,下一个路由处理函数,总是提示没有这个rotue属性 Traceback (most recent call last): File ...

  4. scrapy_创建_调试

    如何创建scrapy项目? 输入命令: scrapy startproject project_name 在当前目录下创建名字叫project_name的scrapy项目 命令格式:scrapy st ...

  5. python_爬百度百科词条

    如何爬取? 明确目标:爬取百度百科,定初始百度词条:python,初始URL:http://baike.baidu.com/item/Python,爬取数据量为1000条,值爬取简介,标题,和简介中u ...

  6. 使用jQuery的ajax调用action的例子

    直接使用ajax请求会比较繁琐,但是jQuery为我们提供了简单使用ajax的方法. 下面是一个在jQuery easyUI中,利用ajax请求,使下拉菜单关联文本框的例子.其中ajax请求就是8-1 ...

  7. JAVA中double类型运算结果异常的解决

    问题: 对两个double类型的值进行运算,有时会出现结果值异常的问题.比如: System.out.println(19.99+20); System.out.println(1.0-0.66); ...

  8. Shell脚本小技巧收集

    1.使用python快速搭建一个web服务器 访问端口8000 python -m SimpleHTTPServer 2.获取文件大小 stat -c %s $file stat --printf=' ...

  9. 理解js中的作用域,作用域链以及闭包

    作用域变量作用域的类型:全局变量和局部变量全局作用域对于最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的 <script> var outerVar = " ...

  10. records.config文件配置模板

    # # # Process Records Config File # # <RECORD-TYPE> <NAME> <TYPE> <VALUE (till ...