xcode 如何快速制作可扩展和可折叠的 UITableView(父单元格和子单元格)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36855851/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make an expandable and collapsable UITableView (parent and child cells) in swift?
提问by A.G
I wanted to have a UITableView
which is able to expand and collapse while clicking on cells.
我想要一个UITableView
能够在单击单元格时展开和折叠的对象。
When I load the page, I want the Tableview to be expanded like this and function collapse and expand by clicking on the header(see the date).
当我加载页面时,我希望 Tableview 像这样展开,并通过单击标题来折叠和展开功能(请参阅日期)。
Any help is appreciated.
任何帮助表示赞赏。
回答by A.G
Thanks everyone. I have solved the problem at last.This is the final sample code.
谢谢大家。我终于解决了这个问题,这是最终的示例代码。
1) //Arrays for header and Child cells.
1) //标题和子单元格的数组。
var topItems = [String]()
var subItems = [String]()
//Section index reference
//段索引参考
var selectedIndexPathSection:Int = -1
2) Added Two custom cells. - one as header and other as Cell.
2) 添加了两个自定义单元格。- 一个作为标题,另一个作为单元格。
// AgendaListHeaderTableViewCell.swift
import UIKit
class AgendaListHeaderTableViewCell: UITableViewCell {
@IBOutlet weak var agendaDateLabel: UILabel!
@IBOutlet weak var expandCollapseImageView: UIImageView!
@IBOutlet weak var headerCellButton: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
Child cell:
子单元格:
// AgendaListTableViewCell.swift
import UIKit
class AgendaListTableViewCell: UITableViewCell {
@IBOutlet weak var agendaListContainerView: UIView!
@IBOutlet weak var moduleListTitleLabel: UILabel!
@IBOutlet weak var moduleDueOnStatusLabel: UILabel!
@IBOutlet weak var moduleLocationLabel: UILabel!
@IBOutlet weak var moduleStatusLabel: UILabel!
@IBOutlet weak var moduleDownLoadStatusImageView: UIImageView!
@IBOutlet weak var moduleStatusLeftSideLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
agendaListContainerView.layer.cornerRadius = 3.0
moduleStatusLabel.layer.borderWidth = 0.5
moduleStatusLabel.layer.borderColor = UIColor.clearColor().CGColor
moduleStatusLabel.clipsToBounds = true
moduleStatusLabel.layer.cornerRadius = 5.0
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
3) On View Controller:
3)在视图控制器上:
// AgendaListViewController.swift
import UIKit
class AgendaListViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
@IBOutlet weak var agendaListTableView: UITableView!
var appUIColor:UIColor = UIColor.brownColor()
var topItems = [String]()
var subItems = [String]()
var selectedIndexPathSection:Int = -1
override func viewDidLoad() {
super.viewDidLoad()
topItems = ["26th April 2017","27th April 2017","28th April 2017","29th April 2017","30th April 2017"]
subItems = ["Monday","TuesDay","WednessDay"]
}
override func viewWillAppear(animated: Bool) {
self.title = "AGENDA VIEW"
self.automaticallyAdjustsScrollViewInsets = false
agendaListTableView.tableFooterView = UIView(frame: CGRectZero)
}
//tableview delegate methods
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 85;
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return topItems.count
}
func tableView(tableView: UITableView, estimatedHeightForHeaderInSection section: Int) -> CGFloat {
return 35
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerCell = tableView.dequeueReusableCellWithIdentifier("agendaTableViewHeaderCellD") as! AgendaListHeaderTableViewCell
headerCell.agendaDateLabel.text = topItems[section]as String
//a buttton is added on the top of all UI elements on the cell and its tag is being set as header's section.
headerCell.headerCellButton.tag = section+100
headerCell.headerCellButton.addTarget(self, action: "headerCellButtonTapped:", forControlEvents: UIControlEvents.TouchUpInside)
//minimize and maximize image with animation.
if(selectedIndexPathSection == (headerCell.headerCellButton.tag-100))
{
UIView.animateWithDuration(0.3, delay: 1.0, usingSpringWithDamping: 5.0, initialSpringVelocity: 5.0, options: UIViewAnimationOptions.TransitionCrossDissolve, animations: {
headerCell.expandCollapseImageView.image = UIImage(named: "maximize")
}, completion: nil)
}
else{
UIView.animateWithDuration(0.3, delay: 1.0, usingSpringWithDamping: 5.0, initialSpringVelocity: 5.0, options: UIViewAnimationOptions.TransitionCrossDissolve, animations: {
headerCell.expandCollapseImageView.image = UIImage(named: "minimize")
}, completion: nil)
}
return headerCell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if( selectedIndexPathSection == section){
return 0
}
else {
return self.subItems.count
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let childCell = tableView.dequeueReusableCellWithIdentifier("agendaTableViewCellID", forIndexPath: indexPath) as! AgendaListTableViewCell
childCell.moduleListTitleLabel.text = subItems[indexPath.row] as? String
childCell.moduleLocationLabel.text = subItems[indexPath.row] as? String
childCell.moduleDueOnStatusLabel.text = subItems[indexPath.row] as? String
return childCell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
//button tapped on header cell
func headerCellButtonTapped(sender:UIButton)
{
if(selectedIndexPathSection == (sender.tag-100))
{
selectedIndexPathSection = -1
}
else {
print("button tag : \(sender.tag)")
selectedIndexPathSection = sender.tag - 100
}
//reload tablview
UIView.animateWithDuration(0.3, delay: 1.0, options: UIViewAnimationOptions.TransitionCrossDissolve , animations: {
self.agendaListTableView.reloadData()
}, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
The sample can be downloaded @ https://github.com/alvinreuben/Expand-ColllapseTableView
示例可以在@ https://github.com/alvinreuben/Expand-CollapseTableView下载
回答by Surjeet Rajput
with the help of below method you can do that
借助以下方法,您可以做到
for objective-c
对于目标-c
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
for swift
为了迅速
func tableView(_ tableView: UITableView,heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
just change the height for a row when its get clicked and reload the section.
只需在单击并重新加载该部分时更改行的高度即可。
when you design any cell in storyboard don't put bottom constraint on the expandable part.just put top and height constraint.Hope this help :)
当您在故事板中设计任何单元格时,不要在可扩展部分上放置底部约束。只需放置顶部和高度约束。希望这有助于:)
回答by Nischal Hada
**Try to implement below**
import UIKit
class BankDepositsHistoryVC: UIViewController {
@IBOutlet weak var tableView: UITableView!
let NORMAL_HEIGHT:CGFloat = 90
let EXPANDABLE_HEIGHT:CGFloat = 200
var SECTION_OTHER_CARDS = 0
var expandableRow:Int = Int()
override func viewDidLoad() {
super.viewDidLoad()
self.expandableRow = self.historyData.count + 1 // initially there is no expanded cell
self.tableView.reloadData()
}
// MARK: - TableViewDelegate Setup
extension BankDepositsHistoryVC : UITableViewDelegate,UITableViewDataSource {
func numberOfSectionsInTableView(tableView: UITableView) -> Int{
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.historyData.count
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat{
let value = indexPath.section
let row = indexPath.row
switch (value){
case SECTION_OTHER_CARDS:
switch (row){
case self.expandableRow:
return EXPANDABLE_HEIGHT
default:
return NORMAL_HEIGHT
}
default:
return 0
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("DepositsHistoryCell", forIndexPath: indexPath) as! DepositsHistoryCell
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
self.expandableRow = indexPath.row // provide row to be expanded
//self.tableView.reloadSections(NSIndexSet(index: indexPath.row), withRowAnimation: UITableViewRowAnimation.Fade)
self.tableView.reloadData()
}
}