TableView嵌套在CollectionViewCell中

时间:2015-08-14 22:16:25

标签: ios arrays swift uitableview uicollectionview

我试图制作一个TableViews的集合视图,这样每个表格都会包含一个"团队"球员(我们的想法是Players按照他们的评分进行排序,这样每个团队都会在最后。即使在最后也是如此。我在使用合适的玩家填充表格方面遇到了一些麻烦。排序/团队制作代码工作正常,但我无法弄清楚如何在tableView dataSource方法中引用每个表所在的单元格,我需要用各自的玩家填充正确的表格。如果您感到困惑,可能下面的代码会说明我尝试做的事情

class myCollectionViewController: UICollectionViewController, UITableViewDelegate, UITableViewDataSource {

    //MARK: Properties

    //These value are passed by the previous ViewController in PrepareForSegue
    var numberOfTeams = Int?() //2
    var team = Array<Array<Players>>() //The 2D array of Players which contains the already sorted teams

    //for right now this is my temporary solution. See below in TableView Data Source
    var collectionIndex = 0

    //MARK: UICollectionViewDataSource

    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {

        if numberOfTeams != nil
            {return numberOfTeams!}
        else
            {return 2}
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! myCollectionViewCell

        cell.teamTable.dataSource = self
        cell.teamTable.delegate = self
       //teamTable is a UITableView and is set as an Outlet in the CollectionViewCell. Here I'm just setting it 

        return cell
    }

    //MARK: TableView DataSource

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //add correct amount of rows
        return team[0].count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        //reset for refresh so index won't go out of bounds of teams Array
        if collectionIndex == numberOfTeams
            {collectionIndex = 0
             print("reset")
        }

(这(上面)是它失败的地方。视图将正确加载,表格按照应有的方式填充。但是如果滚动到其中一个表格的底部,将调用此方法并刷新表格再次向上滚动时数据错误。代码在下面继续)

        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! teamTableViewCell
        cell.playerName.text = team[collectionIndex][indexPath.row].name
        //playerName is a UILabel set as an outlet in the teamTableViewCell class. also, The class Player has a property "name"

        //once all players are cycled through, add 1 to collectionIndex 
        if team[collectionIndex][indexPath.row] === team[collectionIndex].last
           {collectionIndex += 1}

        return cell
    }
}

如上面的括号中所述,当前的实现存在问题,只是一个临时解决方案,因此我可以继续研究代码的其他方面。我需要的是引用tableView所在的collectionViewCell并更改行

cell.playerName.text = team[collectionIndex][indexPath.row].name

cell.playerName.text = team[--"colletionViewCellIndexHere"--][indexPath.row].name

但我不知道如何在tableview: CellForRowAtIndexPath:方法中引用收集单元indexPath.item或行

我试着和tableView.superView鬼混,但没有运气。任何帮助将不胜感激。提前致谢

1 个答案:

答案 0 :(得分:1)

更好地实现您想要的方法是实际负责将每个表视图管理到单独的视图控制器TeamViewController。每个TeamViewController都有自己的team属性,一组玩家。创建集合视图单元格时,添加新的TeamViewController作为子视图控制器,并将其视图添加为单元格的子视图。只是不要忘记细胞重复使用 - 您只想在每个细胞中添加一个 TeamViewController

这样做可以更好地分离逻辑,并使管理表视图变得更加简单。

修改

正确处理细胞再利用的一个例子:

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! TeamsCell
    embedTeamInTeamsCell(cell, atIndexPath: indexPath)
}

func embedTeamInTeamsCell(cell: TeamsCell, atIndexPath indexPath: NSIndexPath) {
    if cell.teamViewController?.team == teams[indexPath.item] {
        // The cell already has a team view controller, but it's for the wrong team – remove it
        detachTeamFromTeamsCell(cell)
    }

    if cell.teamViewController == nil {
        // The cell doesn't currently have a team view controller – create a new one and add it
        let teamVC = self.storyboard?.instantiateViewControllerWithIdentifier("TeamViewController") as! TeamViewController
        addChildViewController(teamVC)
        cell.addSubview(teamVC.view)
        // ... setup constraints on the newly added subview, or set frame
        teamVC.didMoveToParentViewController(self)
        cell.teamViewController = teamVC
    }
}

func detachTeamFromTeamsCell(cell: TeamsCell) {
    if let teamVC = cell.teamViewController {
        teamVC.willMoveToParentViewController(nil)
        cell.teamViewController = nil
        teamVC.view.removeFromSuperview()
        teamVC.removeFromParentViewController()
    }
}

实际上,最好只重用当前嵌入的TeamViewController实例,而不是在需要更改单元格中的嵌入式团队时完全丢弃它们。然后,只需更改team上的TeamViewController属性就足以重新配置该视图控制器以显示新团队(可能您只需要在tableView.reloadData&中调用team即可#39; s didSet属性观察者 - 取决于你如何构建你的类:)

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! TeamsCell
    if cell.teamViewController == nil {
        // The cell doesn't currently have a team view controller – create a new one and add it
        let teamVC = self.storyboard?.instantiateViewControllerWithIdentifier("TeamViewController") as! TeamViewController
        addChildViewController(teamVC)
        cell.addSubview(teamVC.view)
        // ... setup constraints on the newly added subview, or set frame
        teamVC.didMoveToParentViewController(self)
        cell.teamViewController = teamVC
    }

    cell.teamViewController!.team = teams[indexPath.item]
}


class TeamViewController: UITableViewController {
    //...

    var team: Team? {
        didSet { tableView.reloadData() }
    }
}