【问题标题】:Show diffrent data in UITableView with two UICollectionView用两个 UICollectionView 在 UITableView 中显示不同的数据
【发布时间】:2017-06-27 16:27:17
【问题描述】:

我有一个 UITableView 有一个 UICollectionView 和 我使用numberOfRowsInSection 设置行数并使用cellForRowAt 显示带有标题的单元格:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
    return sectionsArray.count
}

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

    let strname = sectionsArray[indexPath.row]
    if (strname as AnyObject).isEqual(to: "top"){
        tableCellobj = tableView.dequeueReusableCell(withIdentifier: "cellmiddle", for: indexPath) as! TableCellMiddle

        tableCellobj.lblMiddle.text = "\(strname)"
        return tableCellobj
    }
    if (strname as AnyObject).isEqual(to: "bottom") {
        tableCellobj = tableView.dequeueReusableCell(withIdentifier: "cellmiddle", for: indexPath) as! TableCellMiddle

        tableCellobj.lblMiddle.text = "\(strname)"
        return tableCellobj
    }

如您所见,数组sectionsArray 是:

var sectionsArray: NSMutableArray = NSMutableArray()
sectionsArray.add("top")
sectionsArray.add("bottom")

现在表格显示了两行标题“顶部”和“底部”

我有两个不同的数据NSArray 显示在 CollectionView 中:

top = ["1","2","3"]
bottom = ["4","5","6"]

collectionView 有一个标签(在 Storyboard 中标识),所以我使用标签来定义视图和显示数据:

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

    if collectionView.tag == 2 {

        objCollectionViewCellMiddle = collectionView.dequeueReusableCell(withReuseIdentifier: "collectioncellmiddle"
        , for: indexPath) as! CollectionViewCellmiddle

        objCollectionViewCellMiddle.lblMiddle.text = top[indexPath.row] as? String

        return objCollectionViewCellMiddle

    }

现在,TableView 显示了两个 CollectionView,但它在两个 CollectionView 中打印来自 top 数组的相同数据

我想要:

第一个 CollectionView ---> 显示 top 数组

第二个CollectionView ---> 显示bottom 数组

我玩弄了 indexPath.section,但无法让它工作,因为它总是打印“0”

【问题讨论】:

  • 这是因为 uitableview 正在缓存单元格作为性能优化的一部分。尝试为 UItableViewCells 使用不同的单元格标识符。例如cellmiddle1 和 cellmiddle2
  • @firstinq 这意味着我必须从情节提要中添加一个新单元格?
  • 您的 indexPath.section 将始终为 0,因为它只有一个 tableview 部分和每个 collectionview 一个部分

标签: ios swift uitableview uicollectionview uicollectionviewcell


【解决方案1】:

好的,我认为我们需要在这里做的是改变你的设置方式。首先,我们应该将后备数据源更改为值类型,例如[String]

MyViewController 类

class MyViewController: UIViewController {

    var sectionsArray: [String] = ["top", "bottom"]
    var topSection: [String] = ["1","2","3"]
    var bottomSection: [String] = ["4","5","6"]

    @IBOutlet weak var myTableView: UITableView!
    @IBOutlet weak var topCollectionView: UICollectionView!
    @IBOutlet weak var bottomCollectionView: UICollectionView!

}

然后,我们需要修改表格视图和集合视图的数据源:

表格视图数据源

extension MyViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return sectionsArray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let sectionName = sectionsArray[indexPath.section]

        switch sectionName {
        case "top":
            let tableCell = tableView.dequeueReusableCell(withIdentifier: "cellmiddle", for: indexPath) as! TableCellMiddle
            tableCell.lblMiddle.text = sectionName
            return tableCell
        case "bottom":
            let tableCell = tableView.dequeueReusableCell(withIdentifier: "cellmiddle", for: indexPath) as! TableCellMiddle
            tableCell.lblMiddle.text = sectionName
            return tableCell
        default:
            return UITableViewCell()
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch section {
        case 0:
            return topSection.count
        case 1:
            return bottomSection.count
        default:
            return 0
        }
    }
}

在这里,在cellForRow 方法中,您实际上可以减少一些重复代码,因为无论您在哪个单元格都在做同样的事情。

集合查看数据源

extension MyViewController: UICollectionViewDataSource {

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        switch collectionView {
        case topCollectionView:
            return topSection.count
        case bottomCollectionView:
            return bottomSection.count
        default:
            return 0
        }
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        switch collectionView {
        case topCollectionView:
            let collectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectioncellmiddle", for: indexPath) as! CollectionViewCellmiddle
            collectionCell.lblMiddle.text = topSection[indexPath.row]
            return collectionCell
        case bottomCollectionView:
            let collectionCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectioncellmiddle", for: indexPath) as! CollectionViewCellmiddle
            collectionCell.lblMiddle.text = bottomSection[indexPath.row]
            return collectionCell
        default:
            return UICollectionViewCell()
        }
    }
}

我们正在做的是打开实际的集合视图本身,它作为参数而不是您设置的标签传入,这样我们就可以很容易地看到当前正在访问哪个集合视图。一旦我们知道这一点,我们就能够确定我们需要访问哪些支持数组,并可以相应地分配文本。

如果你愿意,你也可以在这个方法中减少一些重复的逻辑。

This 是一个可以编译的游乐场(我稍后会添加功能来演示它,以便它显示在时间轴中)。我认为它会帮助你实现你想要做的事情。

【讨论】:

    【解决方案2】:

    我觉得问题出在这个函数上:

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
    
        if collectionView.tag == 2 {
    
            objCollectionViewCellMiddle = collectionView.dequeueReusableCell(withReuseIdentifier: "collectioncellmiddle"
            , for: indexPath) as! CollectionViewCellmiddle
    
            objCollectionViewCellMiddle.lblMiddle.text = top[indexPath.row] as? String
    
            return objCollectionViewCellMiddle
        }
    }
    

    数据赋值显示:

    objCollectionViewCellMiddle.lblMiddle.text = top[indexPath.row] 作为? 字符串

    我建议你通过添加标记代码来更改tableview代码:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    
        let strname = sectionsArray[indexPath.row]
        if (strname as AnyObject).isEqual(to: "top"){
            tableCellobj = tableView.dequeueReusableCell(withIdentifier: "cellmiddle", for: indexPath) as! TableCellMiddle
    
            Add this: tableCellobj.collectionView.tag = 1
            tableCellobj.lblMiddle.text = "\(strname)"
            return tableCellobj
        }
        if (strname as AnyObject).isEqual(to: "bottom") {
            tableCellobj = tableView.dequeueReusableCell(withIdentifier: "cellmiddle", for: indexPath) as! TableCellMiddle
    
            Add this: tableCellobj.collectionView.tag = 2
            tableCellobj.lblMiddle.text = "\(strname)"
            return tableCellobj
        }
    

    }

    然后:

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
    
        if collectionView.tag == 1 {
    
            objCollectionViewCellMiddle = collectionView.dequeueReusableCell(withReuseIdentifier: "collectioncellmiddle"
            , for: indexPath) as! CollectionViewCellmiddle
    
            objCollectionViewCellMiddle.lblMiddle.text = top[indexPath.row] as? String
    
            return objCollectionViewCellMiddle
        }
        else {
    
            objCollectionViewCellMiddle = collectionView.dequeueReusableCell(withReuseIdentifier: "collectioncellmiddle"
            , for: indexPath) as! CollectionViewCellmiddle
    
            objCollectionViewCellMiddle.lblMiddle.text = bottom[indexPath.row] as? String
    
            return objCollectionViewCellMiddle
        } 
    }
    

    【讨论】:

    • 我认为你弄错了tag,因为它在情节提要中的视图中定义,唯一的管理方法是找到一种方法,使用基于indexPath.section 的语句来分隔两个数组或类似的东西
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    相关资源
    最近更新 更多