如何为集合视图创建多个数据源?

时间:2017-11-18 03:25:38

标签: ios swift uitableview uicollectionview

我在这些单元格中有一个包含两个单元格和两个嵌入式集合视图的tableview。当我的应用程序试图对第二个单元格进行duque时,它会一直崩溃。我使用Ash Furrows教程作为这个项目的基础,我将在这里链接。 Tutorial link

如何解决此问题?这是一些示例代码。

我有两个不同的单元格,每个单元格都有自己的类,代码为

    class TableViewCell: UITableViewCell {

    @IBOutlet weak var collectionView: UICollectionView!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

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

        // Configure the view for the selected state
    }

    func setCollectionViewDataSourceDelegate <D: UICollectionViewDataSource & UICollectionViewDelegate> (dataSourceDelegate: D, forRow row: Int) {
        collectionView.delegate = dataSourceDelegate
        collectionView.dataSource = dataSourceDelegate
        collectionView.tag = row
        collectionView.reloadData()
    }
}

这是代码的其余部分,显示我如何将我的单元格出列

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if indexPath.section == 1 {
            guard let tableViewCell = cell as? TableViewCell else {
                return
            }

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

        if indexPath.section == 2 {
            guard let tableViewCell2 = cell as? TableViewCell2 else {
                return
            }
            tableViewCell2.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.row)
        }


        // we store the offset from here into the dictionary we created above
        //tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
    }

    func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        guard let tableViewCell = cell as? TableViewCell else { return }

        storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print(indexPath)
    }
}

// collectionView inside tableview cell

extension TabViewController1: UICollectionViewDelegate, UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return model[collectionView.tag].count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {


        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as? CollectionCell1 {
            cell.backgroundColor = UIColor.gray
            return cell
        }

        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell2", for: indexPath) as? CollectionCell2 {
            cell.backgroundColor = UIColor.purple
            return cell
        }

        return UICollectionViewCell()
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("Collection view at row \(collectionView.tag) selected index path \(indexPath)")
    }
}

非常感谢任何帮助!

编辑:这是整个视图控制器类

    class TabViewController1: UIViewController, UITableViewDelegate {

    @IBOutlet private var tableView: UITableView!

    var model: [[UIColor]] = []

    // Here we create a new dictionary to store the offests, corresponding to their rows.
    var storedOffsets = [Int: CGFloat]()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        print("tab1")

        model = generateRandomData()
        tableView.delegate = self
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("tab 1 viewWillAppear")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func generateRandomData() -> [[UIColor]] {
        let numberOfRows = 20
        let numberOfItemsPerRow = 15

        return (0..<numberOfRows).map { _ in
            return (0..<numberOfItemsPerRow).map { _ in UIColor.randomColor() }
        }
    }
}

extension TabViewController1: UITableViewDataSource {

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if section == 3 {
            return 1
        }
        if section == 4 {
            return 6
        } else {
            return 1
        }
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        if indexPath.section == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "featuredPicture", for: indexPath) as! FeaturedVideoTableViewCell
            return cell
        }

        if indexPath.section == 1 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
            return cell
        }


        if indexPath.section == 2 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "Cell2", for: indexPath) as! TableViewCell2
            return cell
        }

        if indexPath.section == 3 {

            let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell", for: indexPath) as! HeaderTableViewCell
            return cell
        }

        if indexPath.section == 4 {

            let cell = tableView.dequeueReusableCell(withIdentifier: "categoryCell", for: indexPath) as! CategoryTableViewCell
            return cell
        }

        return UITableViewCell()

    }

    // titleForHeaderInSection doesnt get called because I implemented the bottom method which is `viewForHeaderInSection`.
    // I am trying to figure out if we can use both at the same time
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

        if section == 0 {
            return "Featured"
        }

        if section == 1 {
            return "Cool Stuff"
        }

        if section == 2 {
            return "Awesome Stuff"
        }

        if section == 3 {
            return "nothing"
        }

        if section == 4 {
            return "Categories"
        }

        return String()
    }

    // viewForHeaderInSection
//  func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
//      if section == 3 {
//          let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell") as! HeaderTableViewCell
//          return cell
//      }
//      return UIView()
//  }

//  func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
//      if section == 3 {
//          return 50
//      }
//      return CGFloat()
//  }

    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if indexPath.section == 1 {
            guard let tableViewCell = cell as? TableViewCell else {
                return
            }

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

        if indexPath.section == 2 {
            guard let tableViewCell2 = cell as? TableViewCell2 else {
                return
            }
            tableViewCell2.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.row)
        }


        // we store the offset from here into the dictionary we created above
        //tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0
    }

    func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        guard let tableViewCell = cell as? TableViewCell else { return }

        storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.section == 0 {
            return 350
        }

        if indexPath.section == 1 {
            return 130
        }

        if indexPath.section == 2 {
            return 200
        }

        if indexPath.section == 3 {
            return 50
        }

        if indexPath.section == 4 {
            return 220
        }

        return CGFloat()
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print(indexPath)
    }
}

// collectionView inside tableview cell

extension TabViewController1: UICollectionViewDelegate, UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return model[collectionView.tag].count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as? CollectionCell1 {
            cell.backgroundColor = UIColor.gray
            return cell
        }

        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell2", for: indexPath) as? CollectionCell2 {
            cell.backgroundColor = UIColor.purple
            return cell
        }

        return UICollectionViewCell()
    }


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("Collection view at row \(collectionView.tag) selected index path \(indexPath)")
    }
}

1 个答案:

答案 0 :(得分:0)

如果没有看到你在哪里注册你的手机课程,很难肯定地说,但我怀疑你是否已经找回了TableViewCell2以外的其他东西(或任何地方&#39) ; s实际上崩溃)在你的-cellForRow ...或-cellForItemAt ......方法中。你所有的力量展开(!)都可能导致问题。在崩溃之前放置断点,并检查您从-dequeueReusableCell调用中实际返回的内容。