美文网首页
Swift TableView Cell折叠展开效果+隐藏Hea

Swift TableView Cell折叠展开效果+隐藏Hea

作者: Guomingjian | 来源:发表于2020-09-01 16:41 被阅读0次

PS:依赖库 pod 'SnapKit', '~> 4.2.0'
let kJustExpandOne: Bool = true 控制是否显示多条或一条
1、效果图01-可任意展开多条

折叠展开效果01.gif

2、效果图02-只展示一条

折叠展开效果02.gif

源码

//
//  ProblemFeedbackViewController.swift
//  MicroCoupletTaxi
//
//  Created by 郭明健 on 2020/8/31.
//  Copyright © 2020 GuoMingJian. All rights reserved.
//

import UIKit
import SnapKit

class ProblemFeedbackViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    
    var dataSourceArray: NSMutableArray = NSMutableArray()
    let kJustExpandOne: Bool = true // 是否仅展开一条数据
    
    lazy var tableView: UITableView = {
        let tableView = UITableView.init(frame: .zero, style: .grouped)
        tableView.dataSource = self
        tableView.delegate = self
        tableView.backgroundColor = UIColor.white
        tableView.showsVerticalScrollIndicator = false
        tableView.bounces = true
        tableView.separatorStyle = .none
        // 隐藏Header、Footer
        tableView.tableHeaderView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: CGFloat.leastNormalMagnitude))
        tableView.sectionHeaderHeight = 0
        tableView.sectionFooterHeight = 0
        // 注册Cell
        tableView.register(ProblemCell.classForCoder(), forCellReuseIdentifier: ProblemCell.description())
        return tableView
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //
        configNavigationBar()
        setupUI()
        setData()
    }
    
    func configNavigationBar() {
        self.title = "问题反馈"
    }
    
    func setupUI() {
        self.view.addSubview(tableView)
        tableView.snp_makeConstraints { (make) in
            make.center.size.equalToSuperview()
        }
    }
    
    func setData() {
        //
        var dic = NSMutableDictionary.init()
        dic.addEntries(from: ["isOpen" : 0,
                              "problem" : "您需支付取消费的情况",
                              "answer" : "1. 若您在1分钟后取消订单,需支付取消(若司机有迟到,拒载行为,您可无需支付)。\n2.取消费金额为2元,用于补偿司机的空驶成本。"])
        dataSourceArray.add(dic)
        dic = NSMutableDictionary.init()
        dic.addEntries(from: ["isOpen" : 0,
                              "problem" : "您无需支付取消费的情况",
                              "answer" : "1.司机未到达时,您在1分钟内取消订单。\n2.司机未在规定时间内(详见软件提示)到达上车点,您取消订单。\n3.司机未朝上车点行驶,或以其他各种理由不来接您时,您取消订单。\n1.司机未到达时,您在1分钟内取消订单。\n2.司机未在规定时间内(详见软件提示)到达上车点,您取消订单。\n3.司机未朝上车点行驶,或以其他各种理由不来接您时,您取消订单。\n1.司机未到达时,您在1分钟内取消订单。\n2.司机未在规定时间内(详见软件提示)到达上车点,您取消订单。\n3.司机未朝上车点行驶,或以其他各种理由不来接您时,您取消订单。"])
        dataSourceArray.add(dic)
        dic = NSMutableDictionary.init()
        dic.addEntries(from: ["isOpen" : 0,
                              "problem" : "你的来自哪里?",
                              "answer" : "中国"])
        dataSourceArray.add(dic)
        dic = NSMutableDictionary.init()
        dic.addEntries(from: ["isOpen" : 0,
                              "problem" : "你的爱好?",
                              "answer" : "写代码"])
        dataSourceArray.add(dic)
    }
    
    //MARK:- UITableViewDataSource
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return dataSourceArray.count
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        let dic: NSMutableDictionary = dataSourceArray[section] as! NSMutableDictionary
        let isOpen: Int = dic.object(forKey: "isOpen") as! Int
        if isOpen == 0 {
            return 1
        } else {
            return 2
        }
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if indexPath.row == 0 {
            return 44
        } else {
            //
            let dic: NSMutableDictionary = dataSourceArray[indexPath.section] as! NSMutableDictionary
            let answer: String = dic.object(forKey: "answer") as! String
            //
            let cell = ProblemCell.init(style: .default, reuseIdentifier: ProblemCell.description())
            let height: CGFloat = cell.getCellHeight(content: answer)
            return height
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: ProblemCell = tableView.dequeueReusableCell(withIdentifier: ProblemCell.description(), for: indexPath) as! ProblemCell
        cell.selectionStyle = .none
        //
        let dic: NSMutableDictionary = dataSourceArray[indexPath.section] as! NSMutableDictionary
        let problem = dic.object(forKey: "problem") as? String
        let answer = dic.object(forKey: "answer") as? String
        let isOpen: Int = dic.object(forKey: "isOpen") as! Int
        if indexPath.row == 0 {
            cell.setRightImageViewIsHidden(isHidden: false)
            cell.rightImageView.image = UIImage.init(named: (isOpen == 1) ? "下箭头" : "右箭头")
            cell.contentLabel.text = problem
            cell.contentView.backgroundColor = UIColor.white
        } else {
            cell.setRightImageViewIsHidden(isHidden: true)
            cell.contentLabel.text = answer
            cell.contentView.backgroundColor = UIColor.init(red: 242/255.0, green: 242/255.0, blue: 247/255.0, alpha: 1.0)
        }
        //
        return cell
    }
    
    //MARK:- UITableViewDelegate
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if indexPath.row == 0 {
            updateData(indexPath: indexPath)
        } else {
        }
    }
    
    //MARK:-
    func updateData(indexPath: IndexPath) {
        //
        if kJustExpandOne {
            // 显示单个
            for i in 0...dataSourceArray.count-1 {
                let dic : NSMutableDictionary = dataSourceArray[i] as! NSMutableDictionary
                var isOpen = dic.object(forKey: "isOpen") as? Int
                let oldStatus = isOpen
                if i != indexPath.section {
                    isOpen = 0
                } else {
                    isOpen = (isOpen == 0) ? 1 : 0
                }
                dic.setValue(isOpen, forKey: "isOpen")
                dataSourceArray.replaceObject(at: i, with: dic)
                //
                let newIndexPath = IndexPath.init(row: 1, section: i)
                if oldStatus == 1 && isOpen == 0 {
                    tableView.deleteRows(at: [newIndexPath], with: .automatic)
                    // 改变原已展开Cell箭头icon
                    let cell: ProblemCell = tableView.cellForRow(at: IndexPath.init(row: 0, section: i)) as! ProblemCell
                    cell.rightImageView.image = UIImage.init(named: (isOpen == 1) ? "下箭头" : "右箭头")
                }
                if oldStatus == 0 && isOpen == 1 {
                    tableView.insertRows(at: [newIndexPath], with: .automatic)
                }
            }
        } else {
            // 可显示多个
            let dic: NSMutableDictionary = dataSourceArray[indexPath.section] as! NSMutableDictionary
            var isOpen = dic.object(forKey: "isOpen") as? Int
            isOpen = (isOpen == 0) ? 1 : 0
            dic.setValue(isOpen, forKey: "isOpen")
            dataSourceArray.replaceObject(at: indexPath.section, with: dic)
            //
            let newIndexPath = IndexPath.init(row: 1, section: indexPath.section)
            if isOpen == 1 {
                tableView.insertRows(at: [newIndexPath], with: .automatic)
            } else {
                tableView.deleteRows(at: [newIndexPath], with: .automatic)
            }
        }
        // 改变箭头icon
        let dic : NSMutableDictionary = dataSourceArray[indexPath.section] as! NSMutableDictionary
        let isOpen = dic.object(forKey: "isOpen") as? Int
        let cell: ProblemCell = tableView.cellForRow(at: indexPath) as! ProblemCell
        cell.rightImageView.image = UIImage.init(named: (isOpen == 1) ? "下箭头" : "右箭头")
    }
    
}

class ProblemCell: UITableViewCell {
    
    var contentLabel: UILabel!
    var rightImageView: UIImageView!
    //
    let rightIconSize: CGSize = CGSize.init(width: 30, height: 30)
    let contentFont: UIFont = UIFont.systemFont(ofSize: 17)
    let topSpac: CGFloat = 10
    let leftSpac: CGFloat = 15
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        //
        setupUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func setupUI() {
        rightImageView = UIImageView.init()
        rightImageView.image = UIImage.init(named: "右箭头")
        self.addSubview(rightImageView)
        rightImageView.snp_makeConstraints { (make) in
            make.size.equalTo(rightIconSize)
            make.right.equalToSuperview().offset(-leftSpac)
            make.centerY.equalToSuperview()
        }
        //
        contentLabel = UILabel.init()
        contentLabel.font = contentFont
        contentLabel.textColor = UIColor.black
        contentLabel.numberOfLines = 0
        self.addSubview(contentLabel)
        contentLabel.snp_makeConstraints { (make) in
            make.top.equalTo(topSpac)
            make.centerY.equalToSuperview()
            make.left.equalTo(leftSpac)
            make.right.equalTo(rightImageView.snp_left)
        }
    }
    
    func setRightImageViewIsHidden(isHidden: Bool) {
        rightImageView.isHidden = isHidden
        if isHidden {
            rightImageView.snp_remakeConstraints { (make) in
                make.size.equalTo(CGSize.zero)
                make.right.equalToSuperview().offset(-leftSpac)
                make.centerY.equalToSuperview()
            }
        } else {
            rightImageView.snp_remakeConstraints { (make) in
                make.size.equalTo(rightIconSize)
                make.right.equalToSuperview().offset(-leftSpac)
                make.centerY.equalToSuperview()
            }
        }
    }
    
    func getCellHeight(content: String) -> CGFloat {
        //
        let w = UIScreen.main.bounds.size.width - (leftSpac*2)
        let rect = (content as NSString).boundingRect(with: CGSize.init(width: w, height: CGFloat.greatestFiniteMagnitude), options: [.truncatesLastVisibleLine, .usesLineFragmentOrigin, .usesFontLeading], attributes: [.font : contentFont], context: nil)
        var height: CGFloat = ceil(rect.size.height) + topSpac*2
        if height < 44 {
            height = 44
        }
        return height
    }
}

Icon 资源

右箭头.png 下箭头.png

相关文章

网友评论

      本文标题:Swift TableView Cell折叠展开效果+隐藏Hea

      本文链接:https://www.haomeiwen.com/subject/wqbvsktx.html