集合视图的组成
- 单元格: 是集合视图中的一个单元格.
- 节: 是集合视图中的一个行数据,由多个单元格构成.
- 补充视图: 节的头和脚.
- 装饰视图: 集合视图中的背景视图.
集合视图类的构成
-
UICollectionView
继承自UIScrollView
. - 单元格类:
UICollectionViewCell
- 布局是由
UICollectionViewLayout
类定义,其子类有流式布局类UICollectionViewFlowLayout
,对于复杂布局也可以自定义布局类.
EventCollectionViewCell.swift代码,自定义集合视图单元格:
import UIKit
class EventCollectionViewCell: UICollectionViewCell {
var imageView: UIImageView!
var label: UILabel!
//重写构造函数,在该构造函数中实例化单元格包含的各个子视图属性对象.
override init(frame: CGRect){
super.init(frame: frame)
//单元格的宽度
let cellWidth: CGFloat = self.frame.size.width
let imageViewWidth: CGFloat = 101
let imageViewHeight: CGFloat = 101
let imageViewTopView: CGFloat = 15
//1.添加ImageView
self.imageView = UIImageView(frame: CGRect(x: (cellWidth - imageViewWidth)/2, y: imageViewTopView, width: imageViewWidth, height: imageViewHeight))
self.addSubview(self.imageView) //子视图添加到单元格视图
//2. 添加标签
let labelWidth: CGFloat = 101
let labelHeight: CGFloat = 16
let labelTopView: CGFloat = 120
self.label = UILabel(frame: CGRect(x: (cellWidth - labelWidth)/2, y: labelTopView, width: labelWidth, height: labelHeight))
self.label.textAlignment = .center
self.label.font = UIFont.systemFont(ofSize: 13)
self.addSubview(self.label)
}
//该构造函数是单元格视图父类要求必须实现的.
//单元格视图父类中声明实现NSCoding协议,子类中要求实现该构造函数(但本例中并未用到该构造函数.)
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
ViewController.swift代码:
import UIKit
//集合视图列数,即:每一行有几个单元格
let COL_NUM = 3
class ViewController: UIViewController , UICollectionViewDelegate, UICollectionViewDataSource {
var events: NSArray!
var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
let plistPath = Bundle.main.path(forResource: "events", ofType: "plist")
//获取属性列表文件中的全部数据
self.events = NSArray(contentsOfFile: plistPath!)
self.setupCollectionView()
}
func setupCollectionView(){
//1. 创建流式布局(从左到右,从上到下)
let layout = UICollectionViewFlowLayout()
//2. 设置每个单元格的尺寸
layout.itemSize = CGSize(width: 80, height: 80)
//3. 设置整个collectionView的内边距
layout.sectionInset = UIEdgeInsets(top: 15,left: 15,bottom: 20,right: 15)
let screenSize = UIScreen.main.bounds.size
//重新设置iPhone6/6s/7/7s/Plus
if (screenSize.height > 568){
layout.itemSize = CGSize(width: 100, height: 100)
layout.sectionInset = UIEdgeInsets(top: 15, left: 15, bottom: 20, right: 15)
}
//4. 设置单元格之间的间距
layout.minimumInteritemSpacing = 5
//创建集合视图UICollectionView对象的构造函数,第一个参数是设置集合视图frame属性,第二个参数是设置布局管理器对象
self.collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
//5. 设置可重用单元格标识与单元格类型
self.collectionView.register(EventCollectionViewCell.self, forCellWithReuseIdentifier: "cellIdentifier")
self.collectionView.backgroundColor = UIColor.white
self.collectionView.delegate = self
self.collectionView.dataSource = self
self.view.addSubview(self.collectionView)
}
//实现数据源协议
//提供视图中节的个数
func numberOfSections(in collectionView: UICollectionView) -> Int {
let num = self.events.count % COL_NUM
if(num == 0){ //偶数
return self.events.count / COL_NUM
} else { //奇数
return self.events.count / COL_NUM + 1
}
}
//提供某个节中的列数
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return COL_NUM
}
//为某个单元格提供显示数据
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
//第一个参数是可重用单元格标识符
//第二个参数是indexPath(一种复杂多维数组结构,常用属性有section和row,section是集合视图节索引,row是集合视图当前节中列(单元格)的索引)
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellIdentifier", for: indexPath) as! EventCollectionViewCell
//计算events集合下表索引
let idx = indexPath.section * COL_NUM + indexPath.row
if(self.events.count <= idx) {//防止下标越界
return cell
}
let event = self.events[idx] as! NSDictionary
cell.label.text = event["name"] as? String
cell.imageView.image = UIImage(named: event["image"] as! String)
return cell
}
//实现委托协议
//选择单元格之后触发
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let event = self.events[(indexPath as NSIndexPath).section * COL_NUM + (indexPath as NSIndexPath).row] as! NSDictionary
print("selection event name: " , event["name"]!)
}
}
image.png
image.png
网友评论