如何在Swift 4的UITableView Cell中创建UICollectionView?
在UITableViewCell中嵌入UICollectionView的完整实现方案
嘿,我懂你想在UITableView的每个Cell里嵌套UICollectionView的需求,结合你给出的静态图片数组,我给你整理一套可直接复用的实现步骤,代码都是Swift的,抄过去就能用:
第一步:创建自定义UITableViewCell(内嵌UICollectionView)
首先得做一个带CollectionView的自定义TableViewCell,同时还要做一个用来展示单张图片的CollectionViewCell,一起搞定布局和数据源传递逻辑:
import UIKit // 用来显示单张图片的CollectionViewCell class MenuCollectionCell: UICollectionViewCell { private let imageView = UIImageView() override init(frame: CGRect) { super.init(frame: frame) setupImageView() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupImageView() { imageView.contentMode = .scaleAspectFill imageView.clipsToBounds = true imageView.translatesAutoresizingMaskIntoConstraints = false contentView.addSubview(imageView) NSLayoutConstraint.activate([ imageView.topAnchor.constraint(equalTo: contentView.topAnchor), imageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), imageView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), imageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor) ]) } func loadImage(_ name: String) { imageView.image = UIImage(named: name) } } // 内嵌CollectionView的自定义TableViewCell class MenuTableViewCell: UITableViewCell { // 接收当前Cell需要展示的图片数组,赋值后自动刷新CollectionView var imageList: [String] = [] { didSet { collectionView.reloadData() } } private let collectionView: UICollectionView override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { // 设置CollectionView为横向滚动的流式布局 let layout = UICollectionViewFlowLayout() layout.scrollDirection = .horizontal layout.itemSize = CGSize(width: 80, height: 80) layout.minimumLineSpacing = 12 layout.minimumInteritemSpacing = 12 collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) super.init(style: style, reuseIdentifier: reuseIdentifier) setupCollectionView() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupCollectionView() { collectionView.translatesAutoresizingMaskIntoConstraints = false contentView.addSubview(collectionView) // 给CollectionView加约束,铺满Cell内容区域(可按需调整边距) NSLayoutConstraint.activate([ collectionView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8), collectionView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16), collectionView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16), collectionView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8), collectionView.heightAnchor.constraint(equalToConstant: 96) ]) // 注册CollectionViewCell collectionView.register(MenuCollectionCell.self, forCellWithReuseIdentifier: "MenuCollectionCell") collectionView.dataSource = self collectionView.delegate = self collectionView.showsHorizontalScrollIndicator = false collectionView.backgroundColor = .clear } } // 实现UICollectionView的数据源和代理 extension MenuTableViewCell: UICollectionViewDataSource, UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return imageList.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MenuCollectionCell", for: indexPath) as? MenuCollectionCell else { return UICollectionViewCell() } cell.loadImage(imageList[indexPath.item]) return cell } }
第二步:在ViewController中配置UITableView
回到你的ViewController,注册自定义Cell,实现TableView的数据源方法,把图片数据传递给每个Cell:
import UIKit class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! // 你的静态图片数组 let menuImage = ["download.jpeg","download (1).jpeg","download (2).jpeg","download (3).jpeg","download (4).jpeg","download (3).jpeg","download (4).jpeg","download (3).jpeg","download (4).jpeg"] // 把数组拆分成每组3张(可按需调整分组数量),每个TableViewCell展示一组 var groupedImages: [[String]] { stride(from: 0, to: menuImage.count, by: 3).map { Array(menuImage[$0..<min($0+3, menuImage.count)]) } } override func viewDidLoad() { super.viewDidLoad() // 注册自定义TableViewCell tableView.register(MenuTableViewCell.self, forCellReuseIdentifier: "MenuTableCell") tableView.dataSource = self tableView.delegate = self tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = 120 // 配合自动行高的预估高度 } } // 实现UITableView的数据源和代理 extension ViewController: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // 返回分组后的数组个数,也就是TableView的行数 return groupedImages.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "MenuTableCell", for: indexPath) as? MenuTableViewCell else { return UITableViewCell() } // 把当前组的图片数组传给Cell cell.imageList = groupedImages[indexPath.row] return cell } }
几个关键注意点
- 图片资源:确保你的图片已经正确添加到项目中,名字和数组里的完全一致(包括大小写)
- 布局调整:可以根据需求修改CollectionView的
itemSize、间距,或者TableViewCell的约束,比如调整CollectionView的高度 - 数据源灵活度:如果不想分组,直接让TableView只显示1行,把整个
menuImage数组传给这个Cell就行 - 自动行高:设置
automaticDimension和estimatedRowHeight能让TableViewCell根据CollectionView的高度自动适配
内容的提问来源于stack exchange,提问作者Gorib Developer
相关产品推荐
相关产品推荐

