[英]TableView inside specific UICollectionViewCell programmatically?
i am trying to add a TableView inside UICollectionViewCell, so i want to manage that cell by myself from TableView.我想在 UICollectionViewCell 中添加一个 TableView,所以我想从 TableView 自己管理那个单元格。 So to be more clear, if indexPath.row is 2, then i want to call my tableView cell's inside collectionview indexPath.row.
所以更清楚的是,如果 indexPath.row 是 2,那么我想调用我的 tableView 单元格的内部 collectionview indexPath.row。
Please check the picture, i have made with red colour what i want to do.请检查图片,我用红色做了我想做的事。 I created everything programmatically, using UICollectionViewController and UICollectionViewControllerFlowLayout.
我使用 UICollectionViewController 和 UICollectionViewControllerFlowLayout 以编程方式创建了所有内容。
For those who need it, i found the solution:对于那些需要它的人,我找到了解决方案:
class CustomizedCell: UICollectionViewCell, UITableViewDataSource, UITableViewDelegate {
var tableView = UITableView()
let cellIdentifier: String = "tableCell"
override func layoutSubviews() {
super.layoutSubviews()
tableView.delegate = self
tableView.dataSource = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellIdentifier)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.value1, reuseIdentifier: cellIdentifier)
cell.textLabel?.text = "1 CUP"
cell.detailTextLabel?.text = "Whole"
return cell
}
}
Then at viewDidLoad method at CollectionView i did this:然后在 CollectionView 的 viewDidLoad 方法中,我这样做了:
collectionView?.register(CustomizedCell.self, forCellWithReuseIdentifier: "cell")
And after that i have called like this at cellForRowAt indexPath method of UICollectionView:之后,我在 UICollectionView 的 cellForRowAt indexPath 方法中这样调用:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomizedCell
return cell
}
You can create a custom UICollectionView cell for that indexpath.您可以为该索引路径创建自定义 UICollectionView 单元格。 And add a tableview in the cell xib.
并在单元格xib 中添加一个tableview。
Implement the delegate methods of tableview in custom cell class.在自定义单元格类中实现 tableview 的委托方法。
class CustomCollectionViewCell: UICollectionViewCell, UITableViewDataSource, UITableViewDelegate
{
@IBOutlet var tableView: UITableView!
override func layoutSubviews()
{
super.layoutSubviews()
tableView.delegate = self
tableView.dataSource = self
}
}
I found a solution that's working for me .我找到了一个对我有用的解决方案。
import UIKit
class FirstCollectionViewCell: UICollectionViewCell {
let cellId = "cellId"
let tableView:UITableView = {
let tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
return tableView
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .blue
addSubview(tableView)
setUpViews()
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0":tableView]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0":tableView]))
}
required init?(coder aDecoder: NSCoder) {
fatalError("init is not done")
}
func setUpViews() {
tableView.delegate = self
tableView.dataSource = self
tableView.register(MyCell.self, forCellReuseIdentifier: cellId)
}
}
extension FirstCollectionViewCell: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! MyCell
cell.label.text = "Testing testing"
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 40.0
}
}
class MyCell:UITableViewCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
setUpViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// creating a label to display some dummy text
let label:UILabel = {
let label = UILabel()
label.text = "test"
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
func setUpViews() {
addSubview(label)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0":label]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0":label]))
}
}
The approaches above don't work well in with the MVC pattern.上述方法不适用于 MVC 模式。 I recommend creating an NSObject subclass which conforms to UITableViewDelegate and UITableViewDataSource.
我建议创建一个符合 UITableViewDelegate 和 UITableViewDataSource 的 NSObject 子类。
For example:例如:
class DataProvider: NSObject, UITableViewDelegate, UITableViewDataSource {
let dataManager = DataManager()
let reuseId = "Cell"
//MARK: - DataSource Methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataManager.data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: reuseId, for: indexPath)
cell.backgroundColor = .yellow
return cell
}
//MARK: - Delegate Methods
}
Now in your UICollectionViewCell subclass you can specify the tableView data source and delegate properties, like so:现在在您的 UICollectionViewCell 子类中,您可以指定 tableView 数据源和委托属性,如下所示:
class ContainerCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var label: UILabel!
@IBOutlet weak var collectionView: UICollectionView!
let dataProvider = DataProvider()
let tableView: UITableView = {
let table = UITableView()
table.translatesAutoresizingMaskIntoConstraints = false
return table
}()
override func awakeFromNib() {
super.awakeFromNib()
addSubview(tableView)
tableView.fillSuperview()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: dataProvider.reuseId)
tableView.delegate = dataProvider
tableView.dataSource = dataProvider
}
}
Perhaps not perfect, but achieves better encapsulation than the above answers.也许并不完美,但比上述答案实现了更好的封装。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.