Expand/collapse section in UITableView in iOS

前端 未结 17 1045
野的像风
野的像风 2020-11-22 08:49

Could somebody tell me the way to perform UITableView expandable/collapsible animations in sections of UITableView as below?

<

17条回答
  •  礼貌的吻别
    2020-11-22 09:31

    To implement the collapsible table section in iOS, the magic is how to control the number of rows for each section, or we can manage the height of rows for each section.

    Also, we need to customize the section header so that we can listen to the tap event from the header area (whether it's a button or the whole header).

    How to deal with the header? It's very simple, we extend the UITableViewCell class and make a custom header cell like so:

    import UIKit
    
    class CollapsibleTableViewHeader: UITableViewCell {
    
        @IBOutlet var titleLabel: UILabel!
        @IBOutlet var toggleButton: UIButton!
    
    }
    

    then use the viewForHeaderInSection to hook up the header cell:

    override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
      let header = tableView.dequeueReusableCellWithIdentifier("header") as! CollapsibleTableViewHeader
    
      header.titleLabel.text = sections[section].name
      header.toggleButton.tag = section
      header.toggleButton.addTarget(self, action: #selector(CollapsibleTableViewController.toggleCollapse), forControlEvents: .TouchUpInside)
    
      header.toggleButton.rotate(sections[section].collapsed! ? 0.0 : CGFloat(M_PI_2))
    
      return header.contentView
    }
    

    remember we have to return the contentView because this function expects a UIView to be returned.

    Now let's deal with the collapsible part, here is the toggle function that toggle the collapsible prop of each section:

    func toggleCollapse(sender: UIButton) {
      let section = sender.tag
      let collapsed = sections[section].collapsed
    
      // Toggle collapse
      sections[section].collapsed = !collapsed
    
      // Reload section
      tableView.reloadSections(NSIndexSet(index: section), withRowAnimation: .Automatic)
    }
    

    depends on how you manage the section data, in this case, I have the section data something like this:

    struct Section {
      var name: String!
      var items: [String]!
      var collapsed: Bool!
    
      init(name: String, items: [String]) {
        self.name = name
        self.items = items
        self.collapsed = false
      }
    }
    
    var sections = [Section]()
    
    sections = [
      Section(name: "Mac", items: ["MacBook", "MacBook Air", "MacBook Pro", "iMac", "Mac Pro", "Mac mini", "Accessories", "OS X El Capitan"]),
      Section(name: "iPad", items: ["iPad Pro", "iPad Air 2", "iPad mini 4", "Accessories"]),
      Section(name: "iPhone", items: ["iPhone 6s", "iPhone 6", "iPhone SE", "Accessories"])
    ]
    

    at last, what we need to do is based on the collapsible prop of each section, control the number of rows of that section:

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      return (sections[section].collapsed!) ? 0 : sections[section].items.count
    }
    

    I have a fully working demo on my Github: https://github.com/jeantimex/ios-swift-collapsible-table-section

    If you want to implement the collapsible sections in a grouped-style table, I have another demo with source code here: https://github.com/jeantimex/ios-swift-collapsible-table-section-in-grouped-section

    Hope that helps.

提交回复
热议问题