swift-使用tableview实现折叠面板的效果

1. 需求描述

仿QQ的好友分组,每组列表可折叠可展开;但此处每组的展现内容的布局形式不一样。故不仅要实现折叠效果还要对每组的cell单独设计。

2. 页面展示

页面展示.png

3. 界面设计

界面设计.png

4. 效果实现

(1)CollapsibleTableViewController.swift

//
//  CollapsibleTableViewController.swift
//  JackUChat
//
//  Created by 徐云 on 2019/3/12.
//  Copyright © 2019 Liy. All rights reserved.
//

import UIKit
import Alamofire
import SwiftyJSON

//
// MARK: - View Controller
//
class CollapsibleTableViewController: UITableViewController {
    
    var sections = sectionsData//扩展-PBBData

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Auto resizing the height of the cell
        tableView.estimatedRowHeight = 44.0
        tableView.rowHeight = UITableView.automaticDimension
        
    }
    
    
}


//
// MARK: - View Controller DataSource and Delegate
//
extension CollapsibleTableViewController {

    override func numberOfSections(in tableView: UITableView) -> Int {
        return sections.count
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sections[section].collapsed ? 0 : sections[section].items.count
    }
    
    // Cell
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: CollapsibleTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CollapsibleTableViewCell ??
            CollapsibleTableViewCell(style: .default, reuseIdentifier: "cell")
        
        if (indexPath.section == 0) {
            let cell: CollapsibleTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CollapsibleTableViewCell ??
                CollapsibleTableViewCell(style: .default, reuseIdentifier: "cell")
            
            let item: Item = sections[indexPath.section].items[indexPath.row]
            
            cell.nameLabel.text = item.name
            cell.detailLabel.text = item.detail
            
            return cell
        }else if (indexPath.section == 1) {
            let cell: CollapsibleCountTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CollapsibleCountTableViewCell ??
                CollapsibleCountTableViewCell(style: .default, reuseIdentifier: "cell")
            
            let item: Item = sections[indexPath.section].items[indexPath.row]
            
            cell.nameLabel.text = item.name
            cell.detailLabel.text = item.detail
            
            return cell
        }else if (indexPath.section == 2) {
            let cell: CollapsibleMachineTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CollapsibleMachineTableViewCell ??
                CollapsibleMachineTableViewCell(style: .default, reuseIdentifier: "cell")
            
            let item: Item = sections[indexPath.section].items[indexPath.row]
            
            cell.nameLabel.text = item.name
            cell.detailLabel.text = item.detail
            
            return cell
        }else if (indexPath.section == 3) {
            let cell: CollapsibleMaintainTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CollapsibleMaintainTableViewCell ??
                CollapsibleMaintainTableViewCell(style: .default, reuseIdentifier: "cell")
            
            let item: Item = sections[indexPath.section].items[indexPath.row]
            
            cell.nameLabel.text = item.name
            cell.detailLabel.text = item.detail
            
            return cell
        }
        
        return cell
        
    }
    
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    // Header
    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "header") as? CollapsibleTableViewHeader ?? CollapsibleTableViewHeader(reuseIdentifier: "header")
        
        header.titleLabel.text = sections[section].name
        header.arrowLabel.text = ">"
        header.setCollapsed(sections[section].collapsed)
        
        header.section = section
        header.delegate = self
        
        return header
    }
    
    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 44.0
    }
    
    override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 1.0
    }

}

//
// MARK: - Section Header Delegate
//
extension CollapsibleTableViewController: CollapsibleTableViewHeaderDelegate {
    
    func toggleSection(_ header: CollapsibleTableViewHeader, section: Int) {
        let collapsed = !sections[section].collapsed
        
        // Toggle collapse
        sections[section].collapsed = collapsed
        header.setCollapsed(collapsed)
        
        tableView.reloadSections(NSIndexSet(index: section) as IndexSet, with: .automatic)
    }
    
}

(2) CollapsibleTableViewHeader.swift

//
//  CollapsibleTableViewHeader.swift
//  JackUChat
//
//  Created by 徐云 on 2019/3/12.
//  Copyright © 2019 Liy. All rights reserved.
//

import UIKit

protocol CollapsibleTableViewHeaderDelegate {
    func toggleSection(_ header: CollapsibleTableViewHeader, section: Int)
}

class CollapsibleTableViewHeader: UITableViewHeaderFooterView {
    
    var delegate: CollapsibleTableViewHeaderDelegate?
    var section: Int = 0
    
    let titleLabel = UILabel()
    let arrowLabel = UILabel()
    
    override init(reuseIdentifier: String?) {
        super.init(reuseIdentifier: reuseIdentifier)
        
        // Content View
        contentView.backgroundColor = UIColor(hex: 0x2E3944)//扩展-ColorHelper
        
        let marginGuide = contentView.layoutMarginsGuide
        
        // Arrow label
        contentView.addSubview(arrowLabel)
        arrowLabel.textColor = UIColor.white
        arrowLabel.translatesAutoresizingMaskIntoConstraints = false
        arrowLabel.widthAnchor.constraint(equalToConstant: 12).isActive = true
        arrowLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
        arrowLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        arrowLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        
        // Title label
        contentView.addSubview(titleLabel)
        titleLabel.textColor = UIColor.white
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        titleLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
        titleLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        titleLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        titleLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        
        //
        // Call tapHeader when tapping on this header
        //
        addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(CollapsibleTableViewHeader.tapHeader(_:))))
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    //
    // Trigger toggle section when tapping on the header
    //
    @objc func tapHeader(_ gestureRecognizer: UITapGestureRecognizer) {
        guard let cell = gestureRecognizer.view as? CollapsibleTableViewHeader else {
            return
        }
        
        delegate?.toggleSection(self, section: cell.section)
    }
    
    func setCollapsed(_ collapsed: Bool) {
        //
        // Animate the arrow rotation (see Extensions.swf)
        //
        arrowLabel.rotate(collapsed ? 0.0 : .pi / 2)
    }
    
}

(3)CollapsibleTableViewCell.swift

//
//  CollapsibleTableViewCell.swift
//  JackUChat
//
//  Created by 徐云 on 2019/3/12.
//  Copyright © 2019 Liy. All rights reserved.
//

import UIKit

class CollapsibleTableViewCell: UITableViewCell {
    
    let nameLabel = UILabel()
    let detailLabel = UILabel()
    
    // MARK: Initalizers
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        let marginGuide = contentView.layoutMarginsGuide
        
        // configure nameLabel
        contentView.addSubview(nameLabel)
        nameLabel.translatesAutoresizingMaskIntoConstraints = false
        nameLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        nameLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
        nameLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        nameLabel.numberOfLines = 0
        nameLabel.font = UIFont.systemFont(ofSize: 16)
        
        // configure detailLabel
        contentView.addSubview(detailLabel)
        detailLabel.lineBreakMode = .byWordWrapping
        detailLabel.translatesAutoresizingMaskIntoConstraints = false
        detailLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        detailLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        detailLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        detailLabel.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 5).isActive = true
        detailLabel.numberOfLines = 0
        detailLabel.font = UIFont.systemFont(ofSize: 12)
        detailLabel.textColor = UIColor.lightGray
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}

(4)CollapsibleCountTableViewCell.swift

//
//  CollapsibleCountTableViewCell.swift
//  JackUChat
//
//  Created by 徐云 on 2019/3/12.
//  Copyright © 2019 Liy. All rights reserved.
//

import UIKit

class CollapsibleCountTableViewCell: UITableViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

    
    let nameLabel = UILabel()
    let detailLabel = UILabel()
    
    // MARK: Initalizers
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        let marginGuide = contentView.layoutMarginsGuide
        
        
        // configure detailLabel
        contentView.addSubview(detailLabel)
        detailLabel.lineBreakMode = .byWordWrapping
        detailLabel.translatesAutoresizingMaskIntoConstraints = false
    
        detailLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        detailLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
        detailLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        
        detailLabel.numberOfLines = 0
        //detailLabel.adjustsFontSizeToFitWidth = true
        detailLabel.font = UIFont.systemFont(ofSize: 12)
        detailLabel.textColor = UIColor.lightGray
        
        
        // configure nameLabel
        contentView.addSubview(nameLabel)
        nameLabel.translatesAutoresizingMaskIntoConstraints = false
        
        nameLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        nameLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        nameLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        nameLabel.topAnchor.constraint(equalTo: detailLabel.bottomAnchor, constant: 5).isActive = true
        
        nameLabel.numberOfLines = 0
        nameLabel.font = UIFont.systemFont(ofSize: 16)
        nameLabel.text = "计件信息"
        
        
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    
}

(5)CollapsibleMachineTableViewCell.swift

//
//  CollapsibleMachineTableViewCell.swift
//  JackUChat
//
//  Created by 徐云 on 2019/3/12.
//  Copyright © 2019 Liy. All rights reserved.
//

import UIKit

class CollapsibleMachineTableViewCell: UITableViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
    
    
    let nameLabel = UILabel()
    let detailLabel = UILabel()
    
    // MARK: Initalizers
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        let marginGuide = contentView.layoutMarginsGuide
        
        
        
        // configure nameLabel
        contentView.addSubview(nameLabel)
        nameLabel.translatesAutoresizingMaskIntoConstraints = false
        
        //        nameLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        //        nameLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
        //        nameLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        
        nameLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
        nameLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        nameLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        
        nameLabel.numberOfLines = 0
        nameLabel.font = UIFont.systemFont(ofSize: 16)
        
        
        
        // configure detailLabel
        contentView.addSubview(detailLabel)
        detailLabel.lineBreakMode = .byWordWrapping
        detailLabel.translatesAutoresizingMaskIntoConstraints = false
        
        //        detailLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        //        detailLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        //        detailLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        //        detailLabel.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 5).isActive = true
        
        detailLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
        detailLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        detailLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        detailLabel.leadingAnchor.constraint(equalTo: nameLabel.trailingAnchor, constant: 15).isActive = true
        
        detailLabel.numberOfLines = 0
        //detailLabel.adjustsFontSizeToFitWidth = true
        detailLabel.font = UIFont.systemFont(ofSize: 12)
        detailLabel.textColor = UIColor.lightGray
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    

}

(6)CollapsibleMaintainTableViewCell.swift

//
//  CollapsibleMaintainTableViewCell.swift
//  JackUChat
//
//  Created by 徐云 on 2019/3/12.
//  Copyright © 2019 Liy. All rights reserved.
//

import UIKit

class CollapsibleMaintainTableViewCell: UITableViewCell {

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

    
    let nameLabel = UILabel()
    let detailLabel = UILabel()
    
    // MARK: Initalizers
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        
        let marginGuide = contentView.layoutMarginsGuide
        
        
        
        // configure nameLabel
        contentView.addSubview(nameLabel)
        nameLabel.translatesAutoresizingMaskIntoConstraints = false
        
        //        nameLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        //        nameLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
        //        nameLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        
        nameLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
        nameLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        nameLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        
        nameLabel.numberOfLines = 0
        nameLabel.font = UIFont.systemFont(ofSize: 16)
        
        
        
        // configure detailLabel
        contentView.addSubview(detailLabel)
        detailLabel.lineBreakMode = .byWordWrapping
        detailLabel.translatesAutoresizingMaskIntoConstraints = false
        
        //        detailLabel.leadingAnchor.constraint(equalTo: marginGuide.leadingAnchor).isActive = true
        //        detailLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        //        detailLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        //        detailLabel.topAnchor.constraint(equalTo: nameLabel.bottomAnchor, constant: 5).isActive = true
        
        detailLabel.topAnchor.constraint(equalTo: marginGuide.topAnchor).isActive = true
        detailLabel.trailingAnchor.constraint(equalTo: marginGuide.trailingAnchor).isActive = true
        detailLabel.bottomAnchor.constraint(equalTo: marginGuide.bottomAnchor).isActive = true
        detailLabel.leadingAnchor.constraint(equalTo: nameLabel.trailingAnchor, constant: 15).isActive = true
        
        detailLabel.numberOfLines = 0
        //detailLabel.adjustsFontSizeToFitWidth = true
        detailLabel.font = UIFont.systemFont(ofSize: 12)
        detailLabel.textColor = UIColor.lightGray
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    
}

(7)数据模型PBBData.swift

//
//  PBBData.swift
//  JackUChat
//
//  Created by 李艳 on 2019/3/11.
//  Copyright © 2019 Liy. All rights reserved.
//

import Foundation

//
// MARK: - Section Data Structure
//
public struct Item {
    var name: String
    var detail: String
    
    public init(name: String, detail: String) {
        self.name = name
        self.detail = detail
    }
}

public struct Section {
    var name: String//对应tableview每个section的表头
    var items: [Item]//对应tableview每个section下的多个cell
    var collapsed: Bool
    
    public init(name: String, items: [Item], collapsed: Bool = true) {
        self.name = name
        self.items = items
        self.collapsed = collapsed
    }
}

public var sectionsData: [Section] = [
    
    Section(name: "工作时间图", items: [
        Item(name: "测试", detail: "数组")
        ]),
    Section(name: "当日计件信息", items: [
        Item(name: "计件数量", detail: "0件"),
        Item(name: "工作时间", detail: "0秒"),
        Item(name: "剪线次数", detail: "0"),
        Item(name: "针数", detail: "0"),
        Item(name: "抬压脚次数", detail: "0")
        ]),
    Section(name: "机器信息", items: [
        Item(name: "机器型号", detail: "-"),
        Item(name: "电控类型编号", detail: "-"),
        Item(name: "电控软件版本", detail: "-"),
        Item(name: "面板软件版本", detail: "-")
        ]),
    Section(name: "保养设置", items: [
        Item(name: "保养周期", detail: "666")
        ])
    
]

拓展:数据模型(DataHelper.swift)可与swift实现tableview分组-防微信通讯录的实现中的模型(Staff.swift)的建立和封装(staffsDict)进行比较和参考。

5. 网络数据获取与解析显示

(1) 网络数据

{
  "code": "0",
  "msg": "success",
  "data": {
    "params": {
      "": null,
      "a": 1,
      "b": 2,
      "c": 3,
      "d": 4,
      "e": 5,
      "f": 6,
      "g": 7,
      "h": 8,
      "i": 9,
      "j": 10,
      "k": 11,
      "l": 12,
      "m": 13,
      "n": 14,
      "o": 15,
      "p": 16,
      "q": 17,
      "r": 18,
      "s": 19,
      "t": 20,
      "u": 21,
      "v": 22,
      "w": 23,
      "x": 24,
      "y": 25,
      "z": 26
    },
    "valid_time": 1552437569,
    "machine": {
      "machine_id": "61",
      "cate": "6",
      "cate2": "109",
      "name": "测试平缝",
      "sn": "jkpf001",
      "channel": "1",
      "price": "0.000",
      "description": null,
      "image": "/upload/image/2018/10/23fed7e680dec25980ac761b216e99b5.jpg",
      "tags": null,
      "protocol": null,
      "location": "",
      "device_id": "45959395",
      "imsi": null,
      "ProductKey": null,
      "DeviceName": null,
      "DeviceSecret": null,
      "IotId": null,
      "lac": "0",
      "ci": "0",
      "csq": "0",
      "rssi": null,
      "lat": "",
      "lng": "",
      "software": null,
      "build_time": "0",
      "hardware": null,
      "ota_time": "0",
      "add_time": "1538985180",
      "is_oem": "0",
      "rent_out": "1",
      "status": "0",
      "status_time": null,
      "login_type": "7",
      "maintain_time": "666",
      "last_time": "2018",
      "params": "{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5,\"f\":6,\"g\":7,\"h\":8,\"i\":9,\"j\":10,\"k\":11,\"l\":12,\"m\":13,\"n\":14,\"o\":15,\"p\":16,\"q\":17,\"r\":18,\"s\":19,\"t\":20,\"u\":21,\"v\":22,\"w\":23,\"x\":24,\"y\":25,\"z\":26}",
      "param_time": "1539581807",
      "parameter": null,
      "params_set": "{\"\":null}",
      "devctrl": "1",
      "sale_type": "0",
      "is_del": "0"
    },
    "companyMachine": {
      "cm_id": "700",
      "company_id": "50",
      "machine_id": "61",
      "ct_id": "0",
      "cate": "0",
      "cust_group": "0",
      "is_rent": "0",
      "is_test": "0",
      "price": "0.000",
      "is_min": "0",
      "min_num": "0",
      "order_total": "0.00",
      "order_money": "0.00",
      "order_num": "0",
      "order_status": "1",
      "is_overdue": "0",
      "bg_time": "1551429719",
      "end_time": "1552034519",
      "del_time": "0",
      "is_lock": "0",
      "force_lock": "0",
      "status": "1",
      "add_time": "1551429719",
      "is_online": "0",
      "devctrl": "1",
      "con_type": "1",
      "sale_type": "0",
      "parent_id": "699",
      "origin": "wxapp_user_id:43",
      "machine_tag": "0",
      "bg_day": "2019-03-01",
      "end_day": "2019-03-08"
    },
    "cust_group": 0,
    "machineCate": {
      "cate_id": "109",
      "sort": "0",
      "parent_id": "6",
      "cate_name": "A5",
      "image": "/upload/image/2018/10/23fed7e680dec25980ac761b216e99b5.jpg",
      "machine_num": "0",
      "unit": "个",
      "time_unit": "秒",
      "is_jtj": "0",
      "tiered_num": "0",
      "tiered_discount": "0.00"
    },
    "is_ota": 1,
    "ota": {
      "ota_id": "4",
      "version": "v1.0.0",
      "size": "36544",
      "target": "dev"
    },
    "state": null,
    "work_time": [],
    "piece": {
      "num": "0件",
      "DevEletime": null,
      "DevRunningtime": null,
      "DevCutcount": null,
      "DevPincount": null,
      "DevActioncount": null,
      "work_time": "0秒"
    }
  }
}

(2)数据解析与显示:CollapsibleTableViewController.swift

func getDetailByAlomafire(machine_id:String) {
        let params:Parameters = ["machine_id":machine_id]
        AlamofireHelper.shareInstance.requestData(.post, url: "machine/detail", parameters: params) { (result) in
            let jsonDictory = JSON(result as Any)
            let code = jsonDictory["code"].string
            let msg = jsonDictory["msg"].string
            if(code == "0"){
                print("成功:"+code!+","+msg!)
                //var workTimes:[String]//工作时间图(work_time)
                let workTimes = jsonDictory["data"]["piece"]["work_time"].string ?? "0"
                self.sections[0].name = "工作时间图"
                self.sections[0].items[0].name = "当前无相关数据"
                self.sections[0].items[0].detail = workTimes
                
                let countNum = jsonDictory["data"]["piece"]["num"].string ?? "0"//计件数量(num)
                let workTime = jsonDictory["data"]["piece"]["work_time"].string ?? "0"//工作时间(work_time)
                let cutCount = jsonDictory["data"]["piece"]["DevCutcount"].string ?? "0"//剪线次数(DevCutcount)
                let pinCount = jsonDictory["data"]["piece"]["DevPincount"].string ?? "0"//针数(DevPincount)
                let actionCount = jsonDictory["data"]["piece"]["DevActioncount"].string ?? "0"//抬压脚次数(DevActioncount)
                self.sections[1].name = "当日计件信息"
                self.sections[1].items[0].name = "计件数量"
                self.sections[1].items[0].detail = countNum
                self.sections[1].items[1].name = "工作时间"
                self.sections[1].items[1].detail = workTime
                self.sections[1].items[2].name = "剪线次数"
                self.sections[1].items[2].detail = cutCount
                self.sections[1].items[3].name = "针数"
                self.sections[1].items[3].detail = pinCount
                self.sections[1].items[4].name = "抬压脚次数"
                self.sections[1].items[4].detail = actionCount
                
                
                let machineCate = jsonDictory["data"]["machine"]["cate"].string ?? "-"//机器型号(cate)
                let hardware = jsonDictory["data"]["machine"]["hardware"].string ?? "-"//电控类型编号(hardware)
                let software = jsonDictory["data"]["machine"]["software"].string ?? "-"//电控软件版本(software)
                let panelSoftware = jsonDictory["data"]["machine"]["software"].string ?? "-"//面板软件版本(假数据)
                self.sections[2].name = "机器信息"
                self.sections[2].items[0].name = "机器型号"
                self.sections[2].items[0].detail = machineCate
                self.sections[2].items[1].name = "电控类型编号"
                self.sections[2].items[1].detail = hardware
                self.sections[2].items[2].name = "电控软件版本"
                self.sections[2].items[2].detail = software
                self.sections[2].items[3].name = "面板软件版本"
                self.sections[2].items[3].detail = panelSoftware
                
                let maintainTime = jsonDictory["data"]["machine"]["maintain_time"].string ?? "-"//保养周期(maintain_time)
                self.sections[3].name = "保养设置"
                self.sections[3].items[0].name = "保养周期"
                self.sections[3].items[0].detail = maintainTime
                
                dump(self.sections)//打印
                //异步获取数据,需在主线程中更新
                OperationQueue.main.addOperation {
                    self.tableView.reloadData()
                    self.tableView.refreshControl?.endRefreshing()//加载完数据后停止下拉刷新动画
                }
            }else{
                print("失败")
            }
            
        }
        
    }

(3)完整代码:CollapsibleTableViewController.swift

//
//  CollapsibleTableViewController.swift
//  JackUChat
//
//  Created by 徐云 on 2019/3/12.
//  Copyright © 2019 Liy. All rights reserved.
//

import UIKit
import Alamofire
import SwiftyJSON

//
// MARK: - View Controller
//
class CollapsibleTableViewController: UITableViewController {
    
    var sections = sectionsData//扩展-DataHelper
    
    //界面传值
    var device : Device!
    var relayName:String = ""
    
    @IBOutlet weak var deviceNameLabel: UILabel!
    @IBOutlet weak var deviceNoLabel: UILabel!
    @IBOutlet weak var relayNameLabel: UILabel!
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Auto resizing the height of the cell
        tableView.estimatedRowHeight = 44.0
        tableView.rowHeight = UITableView.automaticDimension
        
        //self.title = "杰克优产"
        
        showDeviceInfo(device: device)
        
        getDetailByAlomafire(machine_id: device.machine_id)
        
    }
    
    
    func showDeviceInfo(device:Device) {
        deviceNameLabel.text = device.deviceName
        deviceNoLabel.text = device.deviceSn
        relayNameLabel.text = relayName
        
    }
    
    
    func getDetailByAlomafire(machine_id:String) {
        let params:Parameters = ["machine_id":machine_id]
        AlamofireHelper.shareInstance.requestData(.post, url: "machine/detail", parameters: params) { (result) in
            let jsonDictory = JSON(result as Any)
            let code = jsonDictory["code"].string
            let msg = jsonDictory["msg"].string
            if(code == "0"){
                print("成功:"+code!+","+msg!)
                //var workTimes:[String]//工作时间图(work_time)
                let workTimes = jsonDictory["data"]["piece"]["work_time"].string ?? "0"
                self.sections[0].name = "工作时间图"
                self.sections[0].items[0].name = "当前无相关数据"
                self.sections[0].items[0].detail = workTimes
                
                let countNum = jsonDictory["data"]["piece"]["num"].string ?? "0"//计件数量(num)
                let workTime = jsonDictory["data"]["piece"]["work_time"].string ?? "0"//工作时间(work_time)
                let cutCount = jsonDictory["data"]["piece"]["DevCutcount"].string ?? "0"//剪线次数(DevCutcount)
                let pinCount = jsonDictory["data"]["piece"]["DevPincount"].string ?? "0"//针数(DevPincount)
                let actionCount = jsonDictory["data"]["piece"]["DevActioncount"].string ?? "0"//抬压脚次数(DevActioncount)
                self.sections[1].name = "当日计件信息"
                self.sections[1].items[0].name = "计件数量"
                self.sections[1].items[0].detail = countNum
                self.sections[1].items[1].name = "工作时间"
                self.sections[1].items[1].detail = workTime
                self.sections[1].items[2].name = "剪线次数"
                self.sections[1].items[2].detail = cutCount
                self.sections[1].items[3].name = "针数"
                self.sections[1].items[3].detail = pinCount
                self.sections[1].items[4].name = "抬压脚次数"
                self.sections[1].items[4].detail = actionCount
                
                
                let machineCate = jsonDictory["data"]["machine"]["cate"].string ?? "-"//机器型号(cate)
                let hardware = jsonDictory["data"]["machine"]["hardware"].string ?? "-"//电控类型编号(hardware)
                let software = jsonDictory["data"]["machine"]["software"].string ?? "-"//电控软件版本(software)
                let panelSoftware = jsonDictory["data"]["machine"]["software"].string ?? "-"//面板软件版本(假数据)
                self.sections[2].name = "机器信息"
                self.sections[2].items[0].name = "机器型号"
                self.sections[2].items[0].detail = machineCate
                self.sections[2].items[1].name = "电控类型编号"
                self.sections[2].items[1].detail = hardware
                self.sections[2].items[2].name = "电控软件版本"
                self.sections[2].items[2].detail = software
                self.sections[2].items[3].name = "面板软件版本"
                self.sections[2].items[3].detail = panelSoftware
                
                let maintainTime = jsonDictory["data"]["machine"]["maintain_time"].string ?? "-"//保养周期(maintain_time)
                self.sections[3].name = "保养设置"
                self.sections[3].items[0].name = "保养周期"
                self.sections[3].items[0].detail = maintainTime
                
                dump(self.sections)//打印
                //异步获取数据,需在主线程中更新
                OperationQueue.main.addOperation {
                    self.tableView.reloadData()
                    self.tableView.refreshControl?.endRefreshing()//加载完数据后停止下拉刷新动画
                }
            }else{
                print("失败")
            }
            
        }
        
    }
 
}



//
// MARK: - View Controller DataSource and Delegate
//
extension CollapsibleTableViewController {

    override func numberOfSections(in tableView: UITableView) -> Int {
        return sections.count
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sections[section].collapsed ? 0 : sections[section].items.count
    }
    
    // Cell
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: CollapsibleTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CollapsibleTableViewCell ??
            CollapsibleTableViewCell(style: .default, reuseIdentifier: "cell")
        
        if (indexPath.section == 0) {
            let cell: CollapsibleTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CollapsibleTableViewCell ??
                CollapsibleTableViewCell(style: .default, reuseIdentifier: "cell")
            
            let item: Item = sections[indexPath.section].items[indexPath.row]
        
            cell.nameLabel.text = item.name
            cell.detailLabel.text = item.detail
            
            return cell
        }else if (indexPath.section == 1) {
            let cell: CollapsibleCountTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CollapsibleCountTableViewCell ??
                CollapsibleCountTableViewCell(style: .default, reuseIdentifier: "cell")
            
            let item: Item = sections[indexPath.section].items[indexPath.row]
            
            cell.name1Label.text = item.name
            cell.detail1Label.text = item.detail
            
            return cell
        }else if (indexPath.section == 2) {
            let cell: CollapsibleMachineTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CollapsibleMachineTableViewCell ??
                CollapsibleMachineTableViewCell(style: .default, reuseIdentifier: "cell")
            
            let item: Item = sections[indexPath.section].items[indexPath.row]
            
            cell.nameLabel.text = item.name
            cell.detailLabel.text = item.detail
            
            return cell
        }else if (indexPath.section == 3) {
            let cell: CollapsibleMaintainTableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell") as? CollapsibleMaintainTableViewCell ??
                CollapsibleMaintainTableViewCell(style: .default, reuseIdentifier: "cell")
            
            let item: Item = sections[indexPath.section].items[indexPath.row]
            
            cell.nameLabel.text = item.name
            cell.detailLabel.text = item.detail
            
            return cell
        }
        
        return cell
        
    }
    
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
    
    // Header
    override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "header") as? CollapsibleTableViewHeader ?? CollapsibleTableViewHeader(reuseIdentifier: "header")
        
        header.titleLabel.text = sections[section].name
        header.arrowLabel.text = ">"
        header.setCollapsed(sections[section].collapsed)
        
        header.section = section
        header.delegate = self
        
        return header
    }
    
    override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 44.0
    }
    
    override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 1.0
    }

}

//
// MARK: - Section Header Delegate
//
extension CollapsibleTableViewController: CollapsibleTableViewHeaderDelegate {
    
    func toggleSection(_ header: CollapsibleTableViewHeader, section: Int) {
        let collapsed = !sections[section].collapsed
        
        // Toggle collapse
        sections[section].collapsed = collapsed
        header.setCollapsed(collapsed)
        
        tableView.reloadSections(NSIndexSet(index: section) as IndexSet, with: .automatic)
    }
    
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342