首页 > 解决方案 > 在uitableview swift4中展开和折叠多级部分

问题描述

我想在 uitableview 中展开和折叠多级数组,如下所示

为此,我完成了以下代码。

struct CellData {
var opened = Bool()
var subCatTitle = String()
var subCatList = [String]()
}
struct MainModel {
var opened = Bool()
var categoryTitle = String()
var categoryList = [CellData]()
} 

我已经列出了清单

 @IBOutlet var expandableThreeStageTableView: UITableView!
    var arrayList = [CellData]()
    var expandableList = [MainModel]()

func loadData(){
    arrayList.append(CellData(opened: false, subCatTitle: "SubCat1", subCatList: ["Info1","Info2","Info3"]))
    arrayList.append(CellData(opened: false, subCatTitle: "SubCat2", subCatList: ["Info1","Info2","Info3"]))
    arrayList.append(CellData(opened: false, subCatTitle: "SubCat3", subCatList: ["Info1","Info2"]))
    arrayList.append(CellData(opened: false, subCatTitle: "SubCat4", subCatList: ["Info1"]))

    expandableList.append(MainModel(opened: true, categoryTitle: "Cat1", categoryList: arrayList))
    expandableList.append(MainModel(opened: false, categoryTitle: "Cat2", categoryList: arrayList))
    expandableList.append(MainModel(opened: false, categoryTitle: "Cat3", categoryList: arrayList))
}

和委托,数据源方法如下

extension TextFieldAsSearchVC : UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
        return expandableList.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: 
Int) -> Int {
        if expandableList[section].opened{
            if expandableList[section].categoryList[section].opened{
                return 
expandableList[section].categoryList[section].subCatList.count////which extra count should return here
            }else{
                print("COUNT ",expandableList[section].categoryList.count)
                return expandableList[section].categoryList.count + 
1///here +1 is for catname + subcatname

            }
        }else{
            return 1
        }
    }

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

        if indexPath.row == 0{
            let cell = 
expandableThreeStageTableView.dequeueReusableCell(withIdentifier: 
"TextFieldAsSearchVCCell", for: indexPath) as! TextFieldAsSearchVCCell
            cell.lblValue.text = 
expandableList[indexPath.section].categoryTitle
            return cell
        }else if indexPath.row <= 
expandableList[indexPath.section].categoryList.count{
             let cell = 
expandableThreeStageTableView.dequeueReusableCell(withIdentifier: 
"SectionDataCell", for: indexPath) as! SectionDataCell
            cell.rowLabel.text = 
expandableList[indexPath.section].categoryList[indexPath.row - 
1].subCatTitle
            return cell
        }
        else{
            let cell = 
expandableThreeStageTableView.dequeueReusableCell(withIdentifier: 
"SectionDataCell", for: indexPath) as! SectionDataCell
  cell.rowLabel.text = 

 expandableList[indexPath.section].categoryList[indexPath.row].
subCatList[indexPath.row]//how to access rows in subcategories
            return cell
        }
    }
}
extension TextFieldAsSearchVC : UITableViewDelegate{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: 
IndexPath) {
        if indexPath.row == 0{
            if expandableList[indexPath.section].opened{
                expandableList[indexPath.section].opened = false
                //now reload the section
                let sections = IndexSet(integer: indexPath.section)
                expandableThreeStageTableView.reloadSections(sections, 
with: .automatic)
            }else{
                expandableList[indexPath.section].opened = true
                //now reload sections
                let sections = IndexSet(integer: indexPath.section)
                expandableThreeStageTableView.reloadSections(sections, 
with: .automatic)
            }

        }else {
            if 
expandableList[indexPath.section].categoryList[indexPath.row].opened{

expandableList[indexPath.section].categoryList[indexPath.row].opened = 
false
                expandableThreeStageTableView.reloadRows(at: 
[IndexPath(index: indexPath.row)], with: .automatic)
            }else{

expandableList[indexPath.section].categoryList[indexPath.row].opened = 
true
                expandableThreeStageTableView.reloadRows(at: 
[IndexPath(index: indexPath.row)], with: .automatic)
            }
        }
    }
}

从上面的代码中,我可以展开和折叠类别而不是子类别。当我尝试单击子类别时,它给了我一个错误

*** Terminating app due to uncaught exception 
'NSInternalInconsistencyException', reason: 'Invalid index path for use 
with UITableView. Index paths passed to table view must contain exactly 
two indices specifying the section and row. Please use the category on 
NSIndexPath in NSIndexPath+UIKitAdditions.h if possible.'

如何处理这种类型的逻辑?

标签: iosswiftuitableviewcollapseexpand

解决方案


您得到的具体错误发生在这一行:

expandableThreeStageTableView.reloadRows(at: [IndexPath(index: indexPath.row)], with: .automatic)

a需要IndexPatharow和 a section;你只提供一行。所以它应该是这样的:

expandableThreeStageTableView.reloadRows(at: [IndexPath(row: indexPath.row, section: indexPath.section)], with: .automatic)

如果您真的只需要重新加载 current indexPath,只需像这样调用它:

expandableThreeStageTableView.reloadRows(at: [indexPath], with: .automatic)

这将解决您遇到的错误,但我不知道这是否解决了您的问题。


推荐阅读