如何在 Swift 中使用 UITableView 仅使用单元格(NOT SECTION/ HEADER)进行扩展?

How to make Expandable with only Cells (NOT SECTION/ HEADER) with UITableView in Swift?

我研究了有关可扩展 Table 视图的所有 Whosebug,但他们只发布了带有单元格的显示 header。事实上,iOS 15 已经更改了 UITableView 的新设计界面,众所周知 .insetGrouped

基本上 Header 在 .insetGrouped Expandable 的设计界面真的很糟糕。我正在尝试让我的想法仅使用单元格来执行 Expandable 而无需部分。

我的 Table 在此处查看代码:

class HelpViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    struct Object {
        var seactionName: String!
        var seactionObjection: [String]!
        var footerName: String!
    }
   
    var objectArray = [Object]()
    
    
    var TableView = UITableView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        
        objectArray = [
            Object(seactionName: "Header", seactionObjection: ["Expandable Cell", "One Row", "Two Row"],
                   
                footerName: "Footer"),
        
            
            // copy and paste new cells
        ]
   
        title = "Help Center"
        
        view.backgroundColor = UIColor.quaternarySystemFill
    
        TableView.frame = view.bounds
       
        TableView = UITableView(frame: self.view.bounds, style: UITableView.Style.insetGrouped)
        TableView.showsVerticalScrollIndicator = true
        TableView.indicatorStyle = .default
        TableView.register(SliceCell.self, forCellReuseIdentifier: "Slice List")
        
        TableView.delegate = self
        TableView.dataSource = self
        
        view.addSubview(TableView)
    
    }


    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return objectArray[section].seactionObjection.count
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
       
        return objectArray.count
        
    }
    
        func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

            return objectArray[section].seactionName

        }



func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
    return objectArray[section].footerName
}
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "Slice List") as! SliceCell
        
        cell.backgroundColor = .secondarySystemGroupedBackground
            cell.textLabel?.text = objectArray[indexPath.section].seactionObjection[indexPath.row]
            cell.textLabel?.numberOfLines = 0
        
        return cell
    }

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int){
    view.tintColor = .clear
    let header = view as! UITableViewHeaderFooterView
    header.textLabel?.textColor = UIColor.label
}


}

好吧,我可以更改此代码

cell.accessoryType = .disclosureIndicator

至此

 let disclosureIndicatorTapped = UIImageView()
        disclosureIndicatorTapped.image = UIImage(systemName: "chevron.forward") // When tapped automatic to "Chevron.down"
        cell.accessoryView = disclosureIndicatorTapped

知道如何在 UITableView 中使用 Swift 获取可扩展单元格,而不需要 Header 或页脚吗?

谢谢!

您可以向您的对象添加一个布尔“扩展”属性。

numberOfRowsInSection 中,如果 expanded 为 True,return seactionObjection 中的项目数,否则 return 1.

然后,在 didSelectRowAt 中,如果它是某个部分的第一行,则切换该部分对象的 expanded 属性,然后重新加载该部分。

这是您的控制器的修改版本class:

class HelpViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    struct Object {
        var seactionName: String!
        var expanded: Bool!
        var seactionObjection: [String]!
        var footerName: String!
    }
    
    var objectArray = [Object]()
    
    var TableView = UITableView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        
        objectArray = [
            Object(seactionName: "Header 1",
                   expanded: false,
                   seactionObjection: ["Expandable Cell 1", "One Row 1", "Two Row 1"],
                   footerName: "Footer 1"),
            
            Object(seactionName: "Header 2",
                   expanded: false,
                   seactionObjection: ["Expandable Cell 2", "One Row 2", "Two Row 2"],
                   footerName: "Footer 2"),
            
            Object(seactionName: "Header 3",
                   expanded: false,
                   seactionObjection: ["Expandable Cell 3", "One Row 3", "Two Row 3"],
                   footerName: "Footer 3"),
            

            // copy and paste new cells
        ]
        
        title = "Help Center"
        
        view.backgroundColor = UIColor.quaternarySystemFill
        
        TableView.frame = view.bounds
        
        TableView = UITableView(frame: self.view.bounds, style: UITableView.Style.insetGrouped)
        TableView.showsVerticalScrollIndicator = true
        TableView.indicatorStyle = .default
        TableView.register(SliceCell.self, forCellReuseIdentifier: "Slice List")
        
        TableView.delegate = self
        TableView.dataSource = self
        
        view.addSubview(TableView)
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // if section is expanded
        //  return count of seactionObjection
        // else
        //  return 1
        return objectArray[section].expanded ? objectArray[section].seactionObjection.count : 1
    }
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return objectArray.count
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return objectArray[section].seactionName
    }
    
    func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
        return objectArray[section].footerName
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Slice List") as! SliceCell
        
        cell.backgroundColor = .secondarySystemGroupedBackground
        cell.textLabel?.text = objectArray[indexPath.section].seactionObjection[indexPath.row]
        cell.textLabel?.numberOfLines = 0
        
        // if it's the first row in a section,
        //  show accessoryView with
        //      chevron.up or chevron.down
        //  based on section Object expanded property
        if indexPath.row == 0 {
            let chevronName = objectArray[indexPath.section].expanded ? "chevron.up" : "chevron.down"
            let img = UIImage(systemName: chevronName)
            let disclosureView = UIImageView(image: img)
            cell.accessoryView = disclosureView
        } else {
            // not the first row in a section, so
            //  clear the accessoryView
            cell.accessoryView = nil
        }
    
        return cell
    }
    
    func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int){
        view.tintColor = .clear
        let header = view as! UITableViewHeaderFooterView
        header.textLabel?.textColor = UIColor.label
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.row == 0 {
            objectArray[indexPath.section].expanded.toggle()
            tableView.reloadSections([indexPath.section], with: .automatic)
        } else {
            // do something else on row selection
        }
    }
    
}