扩展可扩展表格进一步查看单元格

时间:2018-06-14 14:19:17

标签: ios swift tableview expandable

我创建了可扩展表格视图单元格,如下图所示。 使用的库是JExpandableTableView

创建此ExpandableTable视图的代码如下:

章节模型:

X'00'

SubCategoryCell模型:

class SectionInfo: NSObject {

    var cells = [CellInfo]()
    var CategoryName: String
    var CategoryCount: String
    var CategoryImage: UIImage

    init(_ text: String,SubCount: String, Image: UIImage ) {

        self.CategoryName = text
        self.CategoryCount = SubCount
        self.CategoryImage = Image
    }
}

查看控制器:

class CellInfo: NSObject {

    var SubcategoryName: String!
    var SubcategoryCount: String!


    init(_ SubName: String, SubCount: String) {

        self.SubcategoryName = SubName
        self.SubcategoryCount = SubCount
    }
}

我的进一步要求是我想扩展Cells(Subcategory 2,SubCategory 2.1)以便在它们存在的情况下容纳SubSubCategory(子类别的子类别)。那么实现这一目标的方法应该是什么呢?

4 个答案:

答案 0 :(得分:1)

您可以通过为SubCategory 2.1创建一个自定义单元格并将其显示在每个部分的第一行中来实现。 然后,在didSelectRow方法中,如果选择了第一行,则将SubCategory 2.1的状态更新为已折叠(或未折叠),重新加载该部分,并在numberOfRows方法中返回根据SubCategory 2.1的状态选择适当的行数。

答案 1 :(得分:1)

UITableView的设计确实可以显示两个级别,部分和行。

但是要显示两个以上的级别,您可以根据部门,子类别的模型来操纵将增加/扩展或减少/折叠的行。

所以表结构看起来像这样

 section_header_1
    subCategory_1.0
        subSubCategory_1.0.1
    subCategory_1.1
        subSubCategory_1.1.1
    subCategory_1.2
        subSubCategory_1.2.1

 section_header_2
    subCategory_2.0
        subSubCategory_2.0.1
    subCategory_2.1
        subSubCategory_2.1.1
    subCategory_2.2
        subSubCategory_2.2.1

对于标题,您必须创建自己的自定义标题行,并将其作为每个节的第一行。您可以像标题一样将单元格设置为LOOK,然后设置tableView:didSelectRowAt来手动展开或折叠该节,subCategory或SubSubCategory所在的部分。第一行之后的行将是您的subCategory和subSubCategory。

然后创建一个用于节SubCategory和SubSubCategory的模型,以存储对应于每个节subCategories的“ expend”值的布尔值。如果只存储其名称,则可以避免使用SubSubCategory模型,但是这样做很容易理解。例如,用于保存Section的结构,SubCategory“ expend”布尔值。

public struct Section {
    var name: String
    var expand: Bool
    var subCategory:[SubCategory]

    public init(name: String, expand: Bool = false ,subCategory: [SubCategory]) {
        self.name = name
        self.expand = expand
        self.subCategory = subCategory
    }
}
public struct SubCategory {
    var name: String
    var expand: Bool
    var subSubCategory: SubSubCategory
    public init(name: String, expand: Bool = false, subSubCategory: SubSubCategory) {
        self.name = name
        self.expand = expand
        self.subSubCategory = subSubCategory
    }
}
public struct SubSubCategory {
    var name: String
    public init(name: String) {
        self.name = name
    }
}

创建3个自定义单元格,一个用于Header,另一个用于SubCategorySubSubCategory,并将其显示在每个部分Header Cell的第一行, 展开或折叠后,相应地显示您的SubCategorySubSubCategory单元格。

毕竟,您的代码应该看起来像这样。

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!
    var sampleData: [Section] = [
        Section(name: "Category 1", expand: false,
                subCategory: [

                    SubCategory(name: "Category 1.1", expand: false, subSubCategory: SubSubCategory(name: "SubSubCategory 1.1.1")),

                    SubCategory(name: "Category 1.2", expand: false, subSubCategory: SubSubCategory(name: "SubSubCategory 1.2.1"))
            ]
        ),
        Section(name: "Category 2", expand: false,
                subCategory: [

                    SubCategory(name: "Category 2.1", expand: false, subSubCategory: SubSubCategory(name: "SubSubCategory 2.1.1")),

                    SubCategory(name: "Category 2.2", expand: false, subSubCategory: SubSubCategory(name: "SubSubCategory 2.2.1"))
            ]
        )
    ]

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    //
    // MARK: - View Controller DataSource and Delegate
    //

    func numberOfSections(in tableView: UITableView) -> Int {
        return sampleData.count
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        var expandCount = 0
        if sampleData[section].expand {
            // if header is expanded all subCategory will be also expanded
            expandCount = sampleData[section].subCategory.count
            for subCategory in sampleData[section].subCategory{
                //check for how many subSubCategory is expanded
                if subCategory.expand{
                    expandCount += 1
                }
            }
        }

        // returning the count of total expanded SubCategories and SubSubCategories
        // 1 is for header you can remove if you are using `viewForHeaderInSection`
        return 1 + expandCount
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // Header cell
        if indexPath.row == 0 {
            let cell = tableView.dequeueReusableCell(withIdentifier: "header")!
            return cell
        }else{

            var countValue = 0
            var indexSubCategory = 0
            let sampleDataSection = sampleData[indexPath.section]

            // check for how many "subCategory" expanded or collapsed
            if sampleDataSection.expand{
                for (index, subCategory) in sampleDataSection.subCategory.enumerated(){

                    countValue += 1
                    if countValue >= indexPath.row{
                        indexSubCategory = index
                        break
                    }
                    // check for how many "subSubCategory" expanded or collapsed
                    if subCategory.expand{
                        if index == sampleDataSection.subCategory.count-1{
                            countValue += 2
                            indexSubCategory = index + 1
                        }else{
                            countValue += 1
                        }
                    }
                }

                // if countValue is grater then indexPath.row it will return "subSubCategory" cell
                // else/countValue = indexPath.row then return "subCategory" cell

                if countValue > indexPath.row{
                    // Cell subSubCategory
                    let cell = tableView.dequeueReusableCell(withIdentifier: "subSubCategory")!
                    cell.textLabel?.text = self.sampleData[indexPath.section].subCategory[indexSubCategory - 1].subSubCategory.name
                    return cell
                }else{
                    // Cell subCategory
                    let cell = tableView.dequeueReusableCell(withIdentifier: "subCategory")!
                    cell.textLabel?.text = self.sampleData[indexPath.section].subCategory[indexSubCategory].name
                    return cell
                }
            }

            else{
                // Cell subCategory
                let cell = tableView.dequeueReusableCell(withIdentifier: "subCategory")!
                cell.textLabel?.text = self.sampleData[indexPath.section].subCategory[indexPath.row].name
                return cell
            }
        }
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // then header cell is selected switch between collapse or expand between "subCategory"
        if indexPath.row == 0{
            let expand = !sampleData[indexPath.section].expand

            //Toggle collapse
            sampleData[indexPath.section].expand = expand
            self.tableView.reloadSections([indexPath.section], with: .none)
        }else{
            var countValue = 0
            var indexSubCategory = 0
            let sampleDataSection = sampleData[indexPath.section]
            if sampleDataSection.expand{
                for (index, subCategory) in sampleDataSection.subCategory.enumerated(){

                    countValue += 1
                    if countValue >= indexPath.row{
                        indexSubCategory = index
                        break
                    }
                    if subCategory.expand{
                        if index == sampleDataSection.subCategory.count-1{
                            countValue += 2
                            indexSubCategory = index + 1
                        }else{
                            countValue += 1
                        }
                    }
                }
                // and if "subCategory" cell is selected switch between collapse or expand between "subSubCategory"
                if countValue == indexPath.row{
                    let subSubCategory = sampleData[indexPath.section].subCategory[indexSubCategory]
                    let expand = !subSubCategory.expand
                    sampleData[indexPath.section].subCategory[indexSubCategory].expand = expand
                    UIView.performWithoutAnimation {
                        self.tableView.reloadSections([indexPath.section], with: .none)
                        self.tableView.layoutIfNeeded()
                    }
                }
            }
        }
    }

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }

    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return CGFloat.leastNormalMagnitude
    }

}

here

下载演示项目

result

答案 2 :(得分:0)

A UITableView really isn't designed to show more than two levels of a hierarchy, as sections and rows.

If you want to show more than two levels there are all deferent type of custom solutions to this, one easy way is to design different cell for Subcategory and display accordingly like showed in the image bellow.

enter image description here

In the above example it is same cell but with different background colour to indicate subcategory.

答案 3 :(得分:0)

我在youtube上看到了这个视频:

Intershop Studio

它可以帮助您实现所需的目标。

但是我认为您可以通过创建自定义UIView并将其放入单元格来实现此目的,这样,当您点击子类别时,它会展开并根据需要显示更多详细信息。

希望这会有所帮助。