Reputation: 14294
I wanted to have a UITableView
which is able to expand and collapse while clicking on cells.
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).
Any help is appreciated.
Upvotes: 3
Views: 7439
Reputation: 3288
**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()
}
}
Upvotes: 0
Reputation: 14294
Thanks everyone. I have solved the problem at last.This is the final sample code.
1) //Arrays for header and Child cells.
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.
// 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:
// 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
Upvotes: 6
Reputation: 1301
with the help of below method you can do that
for objective-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 :)
Upvotes: -1