在uitableview swift4中展开和折叠多级部分

时间:2019-04-10 06:15:15

标签: ios swift uitableview collapse expand

我想像下面那样在uitableview中扩展和折叠多级数组

  • Cat1
    • SubCat1
      • 信息1
      • 信息2
    • SubCat2
      • 信息1
      • 信息2
    • SubCat3
      • 信息1
      • 信息2
  • Cat2
    • SubCat1
      • 信息1
      • 信息2

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

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.'

如何处理这种逻辑?

1 个答案:

答案 0 :(得分:0)

您要获取的特定错误发生在此行:

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

IndexPath同时需要rowsection;您只提供一行。所以应该是这样的:

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

如果您真的只需要重新加载当前的indexPath,只需这样调用即可:

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

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