在uitableview swift4中展开和折叠多级部分
Posted
技术标签:
【中文标题】在uitableview swift4中展开和折叠多级部分【英文标题】:Expand and collapse multilevel sections in uitableview swift4 【发布时间】:2019-08-31 12:23:02 【问题描述】:我想在 uitableview 中展开和折叠多级数组,如下所示
1 类 SubCat1 信息 1 信息 2 子类 2 信息 1 信息 2 SubCat3 信息 1 信息 2 二类 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))
和delegate,datasource方法如下
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.'
如何处理这种类型的逻辑?
【问题讨论】:
而不是为每个数据使用单元格在单元格内使用 stackview 并隐藏/显示 SubCats 【参考方案1】:你得到的具体错误发生在这一行:
expandableThreeStageTableView.reloadRows(at:
[IndexPath(index: indexPath.row)], with: .automatic)
IndexPath
需要 row
和 section
;你只提供一行。所以应该是这样的:
expandableThreeStageTableView.reloadRows(at:
[IndexPath(row: indexPath.row, section: indexPath.section)], with: .automatic)
如果你真的只需要重新加载当前的indexPath
,只需这样调用它:
expandableThreeStageTableView.reloadRows(at:
[indexPath], with: .automatic)
这将解决您遇到的错误,但我不知道这是否解决了您的问题。
【讨论】:
thanx,第二个解决方案已经解决了一个错误。但现在如何在 'cellForRowAt' 方法中访问 SubCat[] 中的索引(行) 我相信您的代码中有多个错误。首先,在您的numbersOfSectionInTableView
实现中:您错误地计算了子类别的数量。你正在这样做:if expandableList[section].opened if expandableList[section].categoryList[section].opened
所以你永远不会到达像expandableList[0].categoryList[1]
这样的条目。您将不得不在这里重新考虑您的逻辑。一个IndexPath
只提供一个部分和一个行。你想要的是一个IndexPath
,它有一个section
、一个subsection
和一个row
。以上是关于在uitableview swift4中展开和折叠多级部分的主要内容,如果未能解决你的问题,请参考以下文章
无法在 Swift 中展开和折叠 TableViewCell