简体   繁体   English

以编程方式在特定 UICollectionViewCell 内的 TableView?

[英]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.

相关问题 自定义UICollectionViewCell(collectionviewcell内的tableview) - Custom UICollectionViewCell (tableview inside collectionviewcell) 如何在 UICollectionViewCell 内制作一个完全展开的 TableView? - How do I make a fully expanded TableView inside of UICollectionViewCell? 添加多个按钮+以编程方式在UICollectionViewCell SWIFT中接收touchUpInside事件 - Adding multiple buttons + receiving touchUpInside event inside UICollectionViewCell SWIFT programmatically 快速,以编程方式更改UICollectionViewCell和UILabel(在单元格内)的宽度 - Swift, Change width of UICollectionViewCell and UILabel(inside the cell) programmatically UICollectionViewCell以编程方式自动布局 - UICollectionViewCell Auto Layout Programmatically 以编程方式编写UICollectionViewCell - Program UICollectionViewCell Programmatically UICollectionViewCell以编程方式内存泄漏 - UICollectionViewCell programmatically memory leak 以编程方式创建的按钮不会收到事件内部的修饰…UICollectionViewCell - Buttons created programmatically doesn't receive touch up inside events… UICollectionViewCell 将UICollectionViewCell固定到特定路径 - Pinning a UICollectionViewCell to a specific path 通过按钮通过内部的tableView以编程方式用UIViewController替换UITableViewController - Programmatically replace UITableViewController by UIViewController with tableView inside via Button
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM