天天看點

Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)

有時要實作一個複雜的頁面布局,單單使用  UITableView 實作不了,需要通過  UITableView 和  UICollectionView 結合實作,即每個單元格  tableViewCell 中都嵌套一個  collectionView。下面通過樣例示範如何實作。

1,效果圖

(1)表格中每一個單元格對應一個月份的圖書清單。 (2)單元格中頭部顯示月份标題。内部通過  collectionView 顯示當月所有書籍封面圖檔,數量不定。整個單元格高度自适應。 (3)這個樣例其實隻用多  section 的  collectionView 也能實作( 點選檢視)。本文使用  UITableView +  UICollectionView 示範如何實作同樣的功能,

Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)

2,如何實作單元格高度自适應

(1)我們要對  collectionView 設定個高度限制。當在單元格中更新  collectionView 的資料時,要擷取這個  collectionView 的真實的内容高度( contentSize.height),然後用  contentSize.height 來更新  collectionView 的高度限制。這樣就實作了單元格内部  collectionView 的高度自适應。 (2)而對于單元格  tableViewCell 的高度自适應,是通過  AutoLayout 特性實作的。利用内容将  cell 撐起來。

1 2 3 4

//設定estimatedRowHeight屬性預設值

self

.tableView!.estimatedRowHeight = 44.0

//rowHeight屬性設定為UITableViewAutomaticDimension

self

.tableView!.rowHeight = 

UITableViewAutomaticDimension

3,實作步驟

(1)建立一個自定義的  collectionView 單元格類: MyCollectionViewCell,同時勾選“ Also create XIB file”

Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)

(2)在  MyCollectionViewCell.xib 中添加一個  ImageView,并設定好限制。同時在對應的類中作關聯

Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)

(3) MyCollectionViewCell.swift 代碼如下:

1 2 3 4 5 6 7 8 9 10 11

import

UIKit

class

MyCollectionViewCell

UICollectionViewCell

{

//用于顯示封面縮略圖

@IBOutlet

weak

var

imageView: 

UIImageView

!

override

func

awakeFromNib() {

super

.awakeFromNib()

}

}

(4)建立一個自定義的  tableView  單元格類: MyTableViewCell ,同時勾選“ Also create XIB file ”

Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)

(5)在  MyTableViewCell.xib 中添加一個  Label 和一個  CollectionView,并設定好限制。同時在對應的類中作關聯。 其中  Label 設定的是上、下、左、右4個限制:

Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)

CollectionView 設定的是左、右、下以及高度這個4個限制:

Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)

(6) MyTableViewCell.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 88 89 90 91 92 93 94 95 96 97

import

UIKit

class

MyTableViewCell

UITableViewCell

UICollectionViewDelegate

UICollectionViewDataSource

{

//單元格标題

@IBOutlet

weak

var

titleLabel: 

UILabel

!

//封面圖檔集合清單

@IBOutlet

weak

var

collectionView: 

UICollectionView

!

//collectionView的高度限制

@IBOutlet

weak

var

collectionViewHeight: 

NSLayoutConstraint

!

//封面資料

var

images:[

String

] = []

override

func

awakeFromNib() {

super

.awakeFromNib()

//設定collectionView的代理

self

.collectionView.delegate = 

self

self

.collectionView.dataSource = 

self

// 注冊CollectionViewCell

self

.collectionView!.register(

UINib

(nibName:

"MyCollectionViewCell"

, bundle:

nil

),

forCellWithReuseIdentifier: 

"myCell"

)

}

//加載資料

func

reloadData(title:

String

, images:[

String

]) {

//設定标題

self

.titleLabel.text = title

//儲存圖檔資料

self

.images = images

//collectionView重新加載資料

self

.collectionView.reloadData()

//更新collectionView的高度限制

let

contentSize = 

self

.collectionView.collectionViewLayout.collectionViewContentSize

collectionViewHeight.constant = contentSize.height

}

//傳回collectionView的單元格數量

func

collectionView(_ collectionView: 

UICollectionView

,

numberOfItemsInSection section: 

Int

) -> 

Int

{

return

images.count

}

//傳回對應的單元格

func

collectionView(_ collectionView: 

UICollectionView

,

cellForItemAt indexPath: 

IndexPath

) -> 

UICollectionViewCell

{

let

cell  = collectionView.dequeueReusableCell(withReuseIdentifier: 

"myCell"

,

for

: indexPath) 

as

MyCollectionViewCell

cell.imageView.image = 

UIImage

(named: images[indexPath.item])

return

cell

}

//繪制單元格底部橫線

override

func

draw(_ rect: 

CGRect

) {

//線寬

let

lineWidth = 1 / 

UIScreen

.main.scale

//線偏移量

let

lineAdjustOffset = 1 / 

UIScreen

.main.scale / 2

//線條顔色

let

lineColor = 

UIColor

(red: 0xe0/255, green: 0xe0/255, blue: 0xe0/255, alpha: 1)

//擷取繪圖上下文

guard 

let

context = 

UIGraphicsGetCurrentContext

() 

else

{

return

}

//建立一個矩形,它的所有邊都内縮固定的偏移量

let

drawingRect = 

self

.bounds.insetBy(dx: lineAdjustOffset, dy: lineAdjustOffset)

//建立并設定路徑

let

path = 

CGMutablePath

()

path.move(to: 

CGPoint

(x: drawingRect.minX, y: drawingRect.maxY))

path.addLine(to: 

CGPoint

(x: drawingRect.maxX, y: drawingRect.maxY))

//添加路徑到圖形上下文

context.addPath(path)

//設定筆觸顔色

context.setStrokeColor(lineColor.cgColor)

//設定筆觸寬度

context.setLineWidth(lineWidth)

//繪制路徑

context.strokePath()

}

override

func

setSelected(_ selected: 

Bool

, animated: 

Bool

) {

super

.setSelected(selected, animated: animated)

}

}

(7)在  StoryBoard 主視圖中添加一個  TableView,并設定好限制。同時在對應的類中作關聯。

Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)

(8) 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

//每月書籍

struct

BookPreview

{

var

title:

String

var

images:[

String

]

}

class

ViewController

UIViewController

UITableViewDelegate

UITableViewDataSource

{

//所有書籍資料

let

books = [

BookPreview

(title: 

"五月新書"

, images: [

"0.jpg"

"1.jpg"

,

"2.jpg"

"3.jpg"

,

"4.jpg"

,

"5.jpg"

,

"6.jpg"

]),

BookPreview

(title: 

"六月新書"

, images: [

"7.jpg"

"8.jpg"

"9.jpg"

]),

BookPreview

(title: 

"七月新書"

, images: [

"10.jpg"

"11.jpg"

"12.jpg"

"13.jpg"

])

]

//顯示内容的tableView

@IBOutlet

weak

var

tableView: 

UITableView

!

override

func

loadView() {

super

.loadView()

}

override

func

viewDidLoad() {

super

.viewDidLoad()

//設定tableView代理

self

.tableView!.delegate = 

self

self

.tableView!.dataSource = 

self

//去除單元格分隔線

self

.tableView!.separatorStyle = .none

//建立一個重用的單元格

self

.tableView!.register(

UINib

(nibName:

"MyTableViewCell"

, bundle:

nil

),

forCellReuseIdentifier:

"myCell"

)

//設定estimatedRowHeight屬性預設值

self

.tableView!.estimatedRowHeight = 44.0

//rowHeight屬性設定為UITableViewAutomaticDimension

self

.tableView!.rowHeight = 

UITableViewAutomaticDimension

}

//在本例中,隻有一個分區

func

numberOfSectionsInTableView(tableView: 

UITableView

) -> 

Int

{

return

1;

}

//傳回表格行數

func

tableView(_ tableView: 

UITableView

, numberOfRowsInSection section: 

Int

) -> 

Int

{

return

self

.books.count

}

//建立各單元顯示内容(建立參數indexPath指定的單元)

func

tableView(_ tableView: 

UITableView

, cellForRowAt indexPath: 

IndexPath

)

-> 

UITableViewCell

{

let

cell = tableView.dequeueReusableCell(withIdentifier: 

"myCell"

)

as

MyTableViewCell

//下面這兩個語句一定要添加,否則第一屏顯示的collection view尺寸,以及裡面的單元格位置會不正确

cell.frame = tableView.bounds

cell.layoutIfNeeded()

//重新加載單元格資料

cell.reloadData(title:books[indexPath.row].title,

images: books[indexPath.row].images)

return

cell

}

override

func

didReceiveMemoryWarning() {

super

.didReceiveMemoryWarning()

}

}

源碼下載下傳:

Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)

hangge_1591.zip

功能修改:每個單元格隻顯示一行封面圖檔

上面的樣例中,每個單元格内的圖檔是全部顯示出來,有多少顯示多少,高度自适應。 我們還可以換種展示方法,每個單元格,即每個  collectionView 隻顯示一行資料,圖檔如果多的話可以通過左右滑動檢視。

1,效果圖

Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)
Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)

2,實作原理

我們隻需要把  collectionView 的滾動方向改成水準方向即可。

Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)

如果不需要顯示橫向的滾動條,可以去掉“ Shows Horizontal Indicator”的勾選。

Swift - 實作表格tableViewCell裡嵌套collectionView(附樣例)

原文出自: www.hangge.com   轉載請保留原文連結: http://www.hangge.com/blog/cache/detail_1591.html