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
网友评论