【问题标题】:How can l put TableView inside CollectionViewCell?我如何将 TableView 放在 CollectionViewCell 中?
【发布时间】:2021-05-02 08:19:12
【问题描述】:

我有一个包含多个单元格的 tableView(由 MVVM 架构创建)。

在 ViewController 中,我像这样填充我的 tableView:

tbv.registerCells(
        withModels:
        FirstViewModel.self,
        SecondViewModel.self,
        ThirdViewModel.self)

我的任务是将我的 TableView 放在 CollectionView 的一个单元格中。我以为我必须在我的 ViewController 中创建 CollectionView,在它创建 CollectionViewCell 和 CollectionCellViewModel 之后,但我不明白该怎么做。

如果你知道如何制作,请帮助。

【问题讨论】:

  • 你是在 SwiftUI 还是 UIKit 中创建的?我可以向你展示我是如何在 UIKit 中做到的,但没有适用于 SwiftUI 的工作示例。
  • @MacUserT 在 UIKit 中。谢谢!
  • 嗨Maytime,当它是正确的答案时,请点击它是正确的答案。仅仅放弃一个档次并不能给我所需的分数。

标签: swift tableview cell collectionview


【解决方案1】:

我如何在我的一个应用程序的集合视图中拥有多个表格视图。首先,我有一个视图控制器,在其中构建我的集合视图。正如新设计指南中通常建议的那样,我在此视图控制器的扩展中拥有 Collection View 委托和数据源。

在您的视图控制器中,您可以为表视图定义一个委托和数据源。优选地,这是一个不同的类。我不会在与您的集合视图相同的视图控制器中拥有 tableview 数据源和委托。

class WorkoutSettingsViewController: UIViewController, LoadWorkoutSettings {

    //MARK: - Properties
    //Used variables

    //Used constants
    private let settingsDelegate = SettingsTableViewDelegate()

扩展名将如下所示。

extension WorkoutSettingsViewController: UICollectionViewDataSource, UICollectionViewDelegate {
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        //Whatever sets your sections
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        //Whatever sets your rows per section
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Workout Settings", for: indexPath) as! SettingsCollectionViewCell
            
        settingsDelegate.workoutTitleLabel = [countdown, mainView, spokenMessage]
        settingsDelegate.mainContentLabel = getSettingsContent()
        cell.settingsTableView.delegate = settingsDelegate
        cell.settingsTableView.dataSource = settingsDelegate
        cell.settingsTableView.reloadData()

        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        
     //Whatever you need as header or footer
}

委托完全按照您希望表视图数据源和委托执行的操作。

class SettingsTableViewDelegate: NSObject, UITableViewDataSource, UITableViewDelegate {
    
    //MARK: - Properties
    //Used variables
    var workoutTitleLabel = [String]()
    var mainContentLabel = [String]()
    var selectedSetting: ((Int) -> ())? = .none
    private var secondaryContentLabel = [String]()
    
    //Used constants
    private let onTitle = NSLocalizedString("ON", comment: "Localized on title")
    private let offTitle = NSLocalizedString("OFF", comment: "Localized off title")
    private let fontColorBlack = UIColor(red: 20.0/255.0, green: 20.0/255.0, blue: 19.0/255.0, alpha: 1.0)
    private let fontColorRed = UIColor(red: 255.0/255.0, green: 96.0/255.0, blue: 89.0/255.0, alpha: 1.0)
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        workoutTitleLabel.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "Settings Cell") as! WorkoutTableViewCell
        
        cell.workoutTitle.text = workoutTitleLabel[indexPath.row]
        cell.mainContent.text = mainContentLabel[indexPath.row]
        cell.secondaryContent.text = ""
        
        (mainContentLabel[indexPath.row] == offTitle) ? (cell.mainContent.textColor = fontColorRed) : (cell.mainContent.textColor = fontColorBlack)
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        selectedSetting?(indexPath.row)
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        61
    }
}

您的收藏视图单元格应如下所示。

class SettingsCollectionViewCell: UICollectionViewCell {
    
    @IBOutlet weak var settingsTableView: UITableView!
}

这应该可以工作。如果您需要从表视图委托/数据源回调到管理您的集合视图的视图控制器,您可以使用闭包。在示例表视图委托中,闭包称为 selectedSettings。在 viewDidLoad 的视图控制器中,您可以像这样定义回调:

override func viewDidLoad() {
    super.viewDidLoad()
    
    settingsDelegate.selectedSetting = { [unowned self] selection in
        startSettingsMenu(for: selection)
    }
    
}

结果如下所示。

亲切的问候, Mac用户T

【讨论】:

    【解决方案2】:

    在 Tableview 的每一行中,您可以通过 collectionviewdata

    加载 UITableViewCell
    //View Controller
    
    var collectionView1Data = ["cell1", "cell2"]
    var collectionView2Data = ["cell1", "cell2"]
    
    //UITableviewDelegate Datasource
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //.....
        if indexPath.row == 1 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "CellID") as? TableviewCell
            cell.collectionData = collectionView1Data /// Collectionviewdata 
            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: "CellID") as? TableviewCell
            cell.collectionData = collectionView2Data
            return cell
        }
    }
    

    ===============================
    每个 Tableviewcell 都包含 CollectionView

    //UITableViewCell
    class TableviewCell: UITableViewCell {
        @IBOutlet weak var collectionView: UICollectionView!
        var collectionData: [String]? {
            didSet {
                guard collectionData != nil else {
                    return
                }
                collectionView.reloadData()
            }
        }
        override func awakeFromNib() {
            super.awakeFromNib()
            collectionView.register(UINib(nibName: "collectionViewCell", bundle: nil), forCellWithReuseIdentifier: "collectionViewCell")
            collectionView.dataSource = self
            collectionView.delegate = self
        }
    }
    
    extension TableviewCell: UICollectionViewDataSource, UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            collectionData.count ?? 0
        }
        
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as? collectionViewCell
            cell...
            return cell
        }
    }
    

    【讨论】:

    • 谢谢,但我不使用 dataSouce/delegates,我必须以我的 MVVM 架构方式 + 使用 rxSwift。但我认为你的回答会对其他人有好处!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多