UICollectionView可以實(shí)現(xiàn)表格布局、流式布局等, 跟UITableView很像。
UICollectionView的布局方式分為Flow和Custom, 默認(rèn)是Flow流式布局。
尺寸屬性:
1、 Cell Size: 單元格大小
2、Header Size: 頁眉大小 (可以實(shí)現(xiàn)類似于Android ListView的headerview)
3、Footer Size: 頁腳大小 (可以實(shí)現(xiàn)類似于Android ListView的footerview)
4、 Min Spacing: 單元格間距
5、Section Insets: 分區(qū)間空白區(qū)域大小
下面講一下UICollectionView最簡單的實(shí)現(xiàn)方式:
1、 打開Main.storyboard, 選中Xcode右下角的UICollectionViewController并拖動(dòng)到storyboard里;
2、 選中UICollectionView并修改Identifier為“simpleCell” (說明:可以隨意命名,在代碼里通過這個(gè)字符串查找復(fù)用的cell);

3、 為了顯示效果在Cell里添加UIImageView和UILable, 并設(shè)置UIImageView的tag為1、UILable的tag為2(從而在代碼里能夠找到引用); tag是整型,范圍是1~1000。

4、拖動(dòng)一個(gè)UIBarButtonItem到左上角,設(shè)置父窗口和子窗口的傳值StorySegue, 在父界面Controller里添加點(diǎn)擊事件函數(shù),函數(shù)必須只有一個(gè)UIStoryBoradSegue類型。
<pre>
@IBAction func unwindToMain(_ segue: UIStoryboardSegue) {
print("unwindToMain 子界面返回?cái)?shù)據(jù)")
//如果是從簡單列表界面返回,拿到子窗口對(duì)象并取值; 類似于Android從intent里拿數(shù)據(jù)
if let controller = segue.source as? SimpleController {
let result = controller.result //模擬返回值
print("子界面返回值:(result), 執(zhí)行當(dāng)前界面邏輯,如刷新界面等")
}
}</pre>
選中左上角的UIBarButtonItem到左邊的Exit選項(xiàng)或者上面的紅色圖標(biāo), 然后選中unwindToMain方法(注意:必須先定義這個(gè)函數(shù),函數(shù)名可以隨便命名,但函數(shù)必須只有一個(gè)UIStoryBoardSegue參數(shù)且添加@IBAction前綴)。


5、添加點(diǎn)擊事件并選中show, 在代碼里覆蓋prepare函數(shù)(打開UIViewController前執(zhí)行), unwind函數(shù)(子窗口返回值處理函數(shù),類似于Android的onActivityResult函數(shù)), 為子窗口賦值(要顯示的數(shù)據(jù))。

<pre>
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("prepare")
if let des = segue.destination as? SimpleController { //判斷要打開的界面
//如果要打開的是最簡單列表
des.data = "最簡單CollectionView" //向子窗口傳遞數(shù)據(jù)
//name是標(biāo)題, pic是要顯示的圖標(biāo)
let resources = [
["name": "廠商", "pic": "聯(lián)系盟商"],
["name": "設(shè)置", "pic": "設(shè)置"],
["name": "提現(xiàn)", "pic": "提現(xiàn)"],
["name": "通知", "pic": "通知"],
["name": "camera", "pic": "camera"]
]
des.resources = resources //子界面要顯示的數(shù)據(jù)
}
}
</pre>
效果圖:

父窗口代碼:
<pre>
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("prepare")
if let des = segue.destination as? SimpleController { //判斷要打開的界面
//如果要打開的是最簡單列表
des.data = "最簡單CollectionView" //向子窗口傳遞數(shù)據(jù)
//name是標(biāo)題, pic是要顯示的圖標(biāo)
let resources = [
["name": "廠商", "pic": "聯(lián)系盟商"],
["name": "設(shè)置", "pic": "設(shè)置"],
["name": "提現(xiàn)", "pic": "提現(xiàn)"],
["name": "通知", "pic": "通知"],
["name": "camera", "pic": "camera"]
]
des.resources = resources //子界面要顯示的數(shù)據(jù)
}
}
override func unwind(for unwindSegue: UIStoryboardSegue, towardsViewController subsequentVC: UIViewController) {
print("unwind")
}
//子窗口返回?cái)?shù)據(jù)。 先在父窗口添加點(diǎn)擊事件,然后在storyboard里設(shè)置exit事件。 類似于Android的onActivityResult
@IBAction func unwindToMain(_ segue: UIStoryboardSegue) {
print("unwindToMain 子界面返回?cái)?shù)據(jù)")
//如果是從簡單列表界面返回,拿到子窗口對(duì)象并取值; 類似于Android從intent里拿數(shù)據(jù)
if let controller = segue.source as? SimpleController {
let result = controller.result //模擬返回值
print("子界面返回值:\(result), 執(zhí)行當(dāng)前界面邏輯,如刷新界面等")
}
}
}
</pre>
子窗口代碼:
<pre>
//從資源里拖出的UICollectionViewController
//UITableView和UICollectionView使用方法類似
class SimpleController: UICollectionViewController {
var data: String? //測試傳值
var result: String? //測試返回值
//name是標(biāo)題, pic是要顯示的圖標(biāo)
var resources: [[String:String]]? //要顯示的數(shù)據(jù)
//設(shè)置標(biāo)題欄背景, 只對(duì)當(dāng)前界面生效
override var preferredStatusBarStyle: UIStatusBarStyle {
return UIStatusBarStyle.lightContent
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
print("父界面?zhèn)髦担?\(data)")
self.title = data ?? "空標(biāo)題" //設(shè)置標(biāo)題
self.collectionView?.backgroundColor = UIColor.white
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// 每個(gè)Section的記錄數(shù)量,同Android的getCount
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return resources!.count
}
// 記錄個(gè)數(shù), 注意indexPath是二維的; 類似于Android的getView
// viewWithTag方法同Android的findViewById
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let identifier = "simpleCell" //在StoryBoard文件里配置的
//取出item布局
let cell = (self.collectionView?.dequeueReusableCell(withReuseIdentifier: identifier,
for: indexPath))! as UICollectionViewCell
let imageView = cell.contentView.viewWithTag(1) as! UIImageView //在storyboard里設(shè)置UIImageView的tag為1
let lable = cell.contentView.viewWithTag(2) as! UILabel //在storyboard里設(shè)置tag為2
imageView.image = UIImage(named: resources![indexPath.item]["pic"]!)
lable.text = resources![indexPath.item]["name"]
return cell //同android的convertView
}
//點(diǎn)擊事件
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("點(diǎn)擊了 \(indexPath.item) ---- \(indexPath.section) --- \(indexPath.row)")
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
print("SimpleController prepare")
//判斷要打開的窗口, 雖然有父界面的對(duì)象,但不要在這個(gè)做父界面的邏輯。
if let _ = segue.destination as? ViewController {
print("準(zhǔn)備打開的界面是父窗口")
}
//判斷點(diǎn)擊了哪個(gè)按鈕
if sender as? UIBarButtonItem == self.navigationItem.leftBarButtonItem {
print("點(diǎn)擊了左上角返回按鈕")
self.result = "列表窗口返回值" //保存當(dāng)前界面的數(shù)據(jù)
}
}
}
</pre>
日志:
prepare
父界面?zhèn)髦担?Optional("最簡單CollectionView")
SimpleController prepare
準(zhǔn)備打開的界面是父窗口
點(diǎn)擊了左上角返回按鈕
unwindToMain 子界面返回?cái)?shù)據(jù)
子界面返回值:Optional("列表窗口返回值"), 執(zhí)行當(dāng)前界面邏輯,如刷新界面等