Swift:如何以编程方式在TableViewCell内部显示CollectionView

问题描述

代码在tableViewCell中显示一个collectionView,其中两个都已添加到StoryBoard中:

class TableViewCell: UITableViewCell {

    @IBOutlet weak var collectionView: UICollectionView!
    override func awakeFromNib() {
        super.awakeFromNib()
       collectionView.delegate = self
        collectionView.dataSource = self
    }

    override func setSelected(_ selected: Bool,animated: Bool) {
        super.setSelected(selected,animated: animated)
    }

}

extension TableViewCell:  UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
    func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell",for: indexPath)
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView,layout collectionViewLayout: UICollectionViewLayout,sizeforItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: 139,height: 64)
    }

在我的应用中,我正在以编程方式创建CollectionView和TableView。

以编程方式创建collectionView:

class collectionViews {
     static func collectionViewOne() -> UICollectionView {
        let flowLayout = CarouselFlowLayout()
        let collectionViewOne = UICollectionView(frame: CGRect(x: 106,y: 313,width: 1708,height: 300),collectionViewLayout: flowLayout)
        return collectionViewOne
    }
}

实例化tableViewCell内部的collectionView:

class TableViewCell2: UITableViewCell {
    var moviesItems: [movieItem] = []
    let cellIdentifier = "movieCardCell"
    let collectionViewOne = collectionViews.collectionViewOne()

    private func setupCollectionView(){

        collectionViewOne.delegate = self
        collectionViewOne.dataSource = self
        collectionViewOne.backgroundColor = UIColor (hex: "444A64")
         collectionViewOne.register(UICollectionViewCell.self,forCellWithReuseIdentifier: "MyCell")
                 let nib = UINib(nibName: "movieCardCell",bundle: nil)
        collectionViewOne.register(nib,forCellWithReuseIdentifier: cellIdentifier)

    }
}

// These functions never get called
 extension TableViewCell:  UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {
 func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection section: Int) -> Int {
     print("INSIDE TableViewCell2.collectionView 1")
     return 1
 }
 
 func collectionView(_ collectionView: UICollectionView,cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell",for: indexPath)
     print("INSIDE TableViewCell2.collectionView 2")
     return cell
 }
 
 func collectionView(_ collectionView: UICollectionView,sizeforItemAt indexPath: IndexPath) -> CGSize {
     // For some reason he chose the measures of collectionViewCell and substracted 2
     print("INSIDE TableViewCell2.collectionView 3")
     return CGSize(width: 139,height: 64)
 }
 }

注意:永远不会调用委托函数。那么collectionView从未添加到tableViewCell吗?

以编程方式创建TableView:

class sectionTableCell: TableViewCell2 {
}
class MoviesViewController4: UIViewController {
    let tableView = UITableView()
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor (hex: "444A64")
        tableView.delegate = self
        tableView.dataSource = self
         tableView.register(sectionTableCell.self,forCellReuseIdentifier: "tableViewCell")
        displayTableView2()
    }

    func displayTableView2() {
        self.view.addSubview(tableView)
        tableView.translatesAutoresizingMaskIntoConstraints = false
        tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
    }
}


extension MoviesViewController4: UITableViewDelegate,UITableViewDataSource {
    func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell =
            tableView.dequeueReusableCell(withIdentifier: "tableViewCell",for: indexPath) as? sectionTableCell
          else {
                fatalError("Unable to create explore table view cell")}
        return cell
    }
    func tableView(_ tableView: UITableView,heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 140
    }
}

所以问题是: 如何将我以编程方式创建的collectionView添加到我也以编程方式创建的tableViewCell中?

解决方法

据我所知,您不会在代码中的任何地方调用setupCollectionView()方法。您应该在UITableViewCell的init方法中执行此操作。 将此代码添加到您的单元格类中:

override init(frame: CGRect) {
    super.init(frame: frame)
    setupCollectionView()
}

required init?(coder: NSCoder) {
    super.init(coder: coder)
    setupCollectionView()
}