天天看点

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