TableView 在 Swift 中展开和折叠单元格

Posted

技术标签:

【中文标题】TableView 在 Swift 中展开和折叠单元格【英文标题】:TableView expand and collapse cells in Swift 【发布时间】:2021-04-29 18:37:52 【问题描述】:

您好,我看过一个关于这个问题的教程,我可以在我的表格视图中打开和关闭点击的部分,但是如果一个部分是打开的,我要打开另一个部分,我希望关闭前一个部分,但我不能。

表格视图代码

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    
    let section = sections[section]
    
    if section.isOpened 
        return section.options.count + 1
     else 
        return 1
    


func numberOfSections(in tableView: UITableView) -> Int 
    
    return sections.count


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    
    if indexPath.row == 0 
        
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell", for: indexPath) as? HeaderView else return UITableViewCell()
        cell.backgroundColor = #colorLiteral(red: 0.9607108235, green: 0.9608257413, blue: 0.9606716037, alpha: 1)
        
        cell.titleLabel?.text = sections[indexPath.section].title
        return cell
        
     else 
        
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "customCell", for: indexPath) as? CustomTableViewCell else return UITableViewCell()
        cell.backgroundColor = #colorLiteral(red: 0.9607108235, green: 0.9608257413, blue: 0.9606716037, alpha: 1)
        
        cell.titleLabel?.text = sections[indexPath.section].options[indexPath.row - 1]
        return cell
    


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)   
    tableView.deselectRow(at: indexPath, animated: true)
    sections[indexPath.section].isOpened = !sections[indexPath.section].isOpened
    tableView.reloadSections([indexPath.section], with: .none)

截面模型

class Section 
    
    let title: String
    let options: [String]
    var isOpened: Bool = false
    
    init(title: String, options: [String], isOpened: Bool = false) 
        
        self.title = title
        self.options = options
        self.isOpened = isOpened
    

ViewDidLoad

sections = [
    
    Section(title: "Spor Giyim 1", options: [1,2,3].compactMap( return "Cell \($0)" ), isOpened: true),
    Section(title: "Spor Giyim 2", options: [1,2,3].compactMap( return "Cell \($0)" ), isOpened: false),
    Section(title: "Spor Giyim 3", options: [1,2,3].compactMap( return "Cell \($0)" ), isOpened: false),
    Section(title: "Spor Giyim 4", options: [1,2,3].compactMap( return "Cell \($0)" ), isOpened: false)
    
]

【问题讨论】:

【参考方案1】:

您需要将它们全部重置为false,然后切换点击部分的当前状态

let toSet = !sections[indexPath.section].isOpened
sections.forEach 
    $0.isOpened = false

sections[indexPath.section].isOpened = toSet
tableView.reloadData()

【讨论】:

用你的代码替换了我的 Didselect 函数,它有效,谢谢,但是我怎么能用动画来做到这一点。 我使用 tableView.reloadSections([indexPath.section], with: .none) 但应用程序崩溃了@Sh_Khan【参考方案2】:

在 viewController 中存储对任何打开部分的引用,使用它来将其重置为关闭,然后重新加载该部分和要打开的部分:

class myVC: UIViewController 
  var openSection: Int?
  // rest of the VC...


func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)   
    tableView.deselectRow(at: indexPath, animated: true)
    if let openSection = openSection, openSection != indexpath.section 
       section[openSection].isOpened = false
       section[indexPath.section].isOpened = true
       tableView.reloadSections([ openSection, indexPath.section], with: .automatic)
       openSection = indexPath.section
     else 
      sections[indexPath.section].isOpened.toggle()
      tableView.reloadSections([indexPath.section], with: .automatic)
      openSection = sections[indexPath.section].isOpened ? indexPath.section : nil
    

【讨论】:

感谢您的回答实际上@Sh_Khans 的回答解决了我的问题,但没有动画。我需要动画。 以上将给出标准的表格视图动画(@Sh_Khans 也会,取决于你如何实现它)。你也可以(如果你是 ios 13+)使用也可以动画的 diffable 数据源 API。如果您想要自定义动画,那是一个完全不同的问题。 哦,谢谢,我的 ios 目标是 10.0,但我以某种方式解决了动画问题

以上是关于TableView 在 Swift 中展开和折叠单元格的主要内容,如果未能解决你的问题,请参考以下文章

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

在 ios 中展开和折叠表格视图单元格

[转]VS中展开和折叠代码

VS中展开和折叠代码,还有其他快捷操作

当我在 ios 中展开和折叠 TableList 单元格时如何更改 UILabel 文本颜色

如何仅通过单击打开和折叠同一个 JQuery 手风琴