TableView内部的CollectionView

时间:2019-06-04 16:43:42

标签: swift uitableview uicollectionview

我在CollectionView单元格中有一个TableViewControllertableView包含3个部分,每个部分属于不同的类别。我如何在每个部分中传递不同的数据。像Netflix应用一样

在UICollectionViewController文件中

import UIKit
import Alamofire

class HomeViewController: UITableViewController, MovieDataDelegate {

    let tableViewHeaderIdentifier = "FeaturedTableHeader"
    var homePresenter : HomePresenter!


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        let headerNib = UINib(nibName: "FeaturedUITableViewHeaderView", bundle: nil)
        tableView.register(headerNib, forHeaderFooterViewReuseIdentifier: tableViewHeaderIdentifier)

        homePresenter = HomePresenter()
        homePresenter.delegate = self
        homePresenter.fetchData()
        homePresenter.fetchImageData()

    }


    func arrayOfMoviesNames(names: [String]) {
        //print(homePresenter.homeData.moviesNamesArray)
        tableView.reloadData()
    }

    func arrayOfPosters(path: [String]) {
        //print(homePresenter.homeData.posterPathsArray)
    }



    //MARK: - Home UI table
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell =  tableView.dequeueReusableCell(withIdentifier: "featuredCell", for: indexPath) as! FeaturedTableViewCell

        cell.homeCollectionView.dataSource = self
        return cell
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 3
    }

    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerView = tableView.dequeueReusableHeaderFooterView(withIdentifier: tableViewHeaderIdentifier) as! FeaturedUITableViewHeaderView

        switch section {
        case 0:
            headerView.isHidden = true
        case 1:
            headerView.catagoryLabel.text = "Popular Movies"
        case 2:
            headerView.catagoryLabel.text = "Celebs"
        default:
            headerView.catagoryLabel.text = "" as String
        }

        return headerView
    }

    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {

        if section == 0 {
            return 0
        }
        return 35
    }

    override func tableView(_ tableView: UITableView, estimatedHeightForFooterInSection section: Int) -> CGFloat {
        return 12
    }

    override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

        guard let tableViewCell = cell as? FeaturedTableViewCell else { return }

        tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row)

    }


}




//MARK: - collectionView
extension HomeViewController : UICollectionViewDataSource, UICollectionViewDelegate {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return homePresenter.homeData.moviesNamesArray.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "homeCollectionCell", for: indexPath) as! HomeCollectionViewCell
        cell.posterImage.image = UIImage(named: "Aladdin")

        cell.movieName.text = "coco"

        return cell
    }


}

在UITableViewCell文件中

import UIKit

class FeaturedTableViewCell: UITableViewCell {

    @IBOutlet weak var homeCollectionView: UICollectionView!


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
        let collectionNib = UINib(nibName: "HomeCollectionViewCell", bundle: nil)
        homeCollectionView.register(collectionNib, forCellWithReuseIdentifier: "homeCollectionCell")
    }

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

        // Configure the view for the selected state
    }

}
extension FeaturedTableViewCell {

     func setCollectionViewDataSourceDelegate<D: UICollectionViewDataSource & UICollectionViewDelegate>(_ dataSourceDelegate: D, forRow row: Int) {

          homeCollectionView.delegate = dataSourceDelegate
          homeCollectionView.dataSource = dataSourceDelegate
          homeCollectionView.tag = row
          homeCollectionView.reloadData()
}

}


screenshot of app

我想为tabelview的每个部分显示不同的图像和文本

2 个答案:

答案 0 :(得分:1)

创建一个结构Movie并在视图控制器中创建一个元组数组。在元组中添加类别标题和一系列相关的电影。在表视图数据源方法中,使用主数组,在集合视图数据源方法中,使用来自相应元组的movies数组。将当前的元组/节索引设置为collectionView标记。并在“集合视图”数据源方法中获取适当的电影数组。

// HomeViewController

class HomeViewController: UITableViewController {
    struct Movie {
        var name: String
        var image: UIImage?
        //other details
    }
    var movieDetails:[(title:String, movies:[Movie])] = []
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(FeaturedCell.self, forCellReuseIdentifier: "FeaturedCell")
        movieDetails = [(title: "MoviesDB", movies: [Movie(name: "a", image: UIImage(named: "a")),
                                                     Movie(name: "b", image: UIImage(named: "b")),
                                                     Movie(name: "c", image: UIImage(named: "c"))]),
                        (title: "Popular Movies", movies: [Movie(name: "d", image: UIImage(named: "d")),
                                                           Movie(name: "e", image: UIImage(named: "e")),
                                                           Movie(name: "f", image: UIImage(named: "f"))]),
                        (title: "Celebs", movies: [Movie(name: "g", image: UIImage(named: "g")),
                                                   Movie(name: "h", image: UIImage(named: "h")),
                                                   Movie(name: "i", image: UIImage(named: "i"))])]
    }
    // MARK: - Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int {
        return movieDetails.count
    }
    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return movieDetails[section].title
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FeaturedCell") as? FeaturedCell ?? FeaturedCell(style: .default, reuseIdentifier: "FeaturedCell")
        cell.collectionView.tag = indexPath.section
        cell.collectionView.delegate = self
        cell.collectionView.dataSource = self
        return cell
    }
}
extension HomeViewController: UICollectionViewDataSource, UICollectionViewDelegate {
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return movieDetails[collectionView.tag].movies.count
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HomeCell", for: indexPath) as? HomeCell ?? HomeCell()
        let movie = movieDetails[collectionView.tag].movies[indexPath.item]
        cell.posterImage.image = movie.image
        cell.movieName.text = movie.name
        return cell
    }
}

// FeaturedCell

class FeaturedCell: UITableViewCell {

    var collectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout())

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        commonInit()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }
    func commonInit() {

        if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
            layout.scrollDirection = .horizontal
        }
        collectionView.register(HomeCell.self, forCellWithReuseIdentifier: "HomeCell")
        collectionView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(collectionView)

        collectionView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        collectionView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
        collectionView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        collectionView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
    }
}

// HomeCell

class HomeCell: UICollectionViewCell {
    let posterImage = UIImageView()
    let movieName = UILabel()
    //...
}

答案 1 :(得分:0)

同时使用UITableView数据源和UICollectionView数据源方法。

UITableView中设置3个部分,每个部分只有一个单元格。

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
}

func numberOfSections(in tableView: UITableView) -> Int {
    return 3
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Your cell with UICollectionView inside
    let cell = tableView.dequeueReusableCell(withIdentifier: "YOUR_TABLE_VIEW_CELL_IDENTIFIER", for: indexPath)
    // Set UICollectionViewDataSource, also add data source methods in your class, look at next code block
    cell.collectionView.dataSource = self
    return cell
}

// Header for each section, 
func tableView(_ tableView: UITableView, 
titleForHeaderInSection section: Int) -> String? {
    if (section == 0) {
        return nil
    } else if (section == 1) {
        return "Popular movies"
    } else if (section == 2) {
        return "Celebs"
    }
}
// UICollectionViewDataSource methods
override func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1 // only one section for each UICOllectionView
  }

  override func collectionView(_ collectionView: UICollectionView,
                               numberOfItemsInSection section: Int) -> Int {
    // return here number of items in each UICollectionView
  }

  override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "YOUR_COLLECTION_CELL_IDENTIFIER", for: indexPath)
    // set real data for each UICollectionCell here
    cell.label = "COCO"
    return cell
  }

如果您想