Reputation: 33
I'm trying to get my tableview to work so when a cell is clicked it resizes to fit the content inside the cell automatically. (Different amounts of text will automatically re-size different.
Cell when not clicked (first state and size it should go back to when clicked = 44.0
So with this image, this is the stage each cell will be in only as default and deselected. The white text will be the only thing visible.
This is my full code for the tableview and viewcontroller.
import UIKit
class TasksViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tblTasks: UITableView!
//For persisting data
let defaults = UserDefaults.standard
override func viewDidLoad() {
super.viewDidLoad()
self.tblTasks.backgroundColor = UIColor(red: 64/255.0, green: 67/255.0, blue: 68/255.0, alpha: 0)
self.tblTasks.reloadData()
self.tblTasks.register(UINib(nibName: "WhiteTaskTableViewCell", bundle: nil), forCellReuseIdentifier: "nameCell")
tblTasks.tableFooterView = UIView()
let darkModeColor = UIColor(red: 52/255.0, green: 55/255.0, blue: 55/255.0, alpha: 1.0)
view.backgroundColor = darkModeColor
tblTasks.dataSource = self;
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
self.tblTasks.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
return taskMgr.tasks.count
}
//Define how our cells look - 2 lines a heading and a subtitle
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let identifier = "nameCell"
var cell: WhiteTaskTableViewCell! = tableView.dequeueReusableCell(withIdentifier: identifier) as? WhiteTaskTableViewCell
if cell == nil {
tableView.register(UINib(nibName: "WhiteTaskTableViewCell", bundle: nil), forCellReuseIdentifier: identifier)
cell = tableView.dequeueReusableCell(withIdentifier: identifier) as? WhiteTaskTableViewCell
}
// Assign the contents of our var "items" to the textLabel of each cell
// cell.textLabel!.text = taskMgr.tasks[indexPath.row].name
// cell.detailTextLabel!.text = taskMgr.tasks[indexPath.row].desc
cell.TaskNameLabel.text = taskMgr.tasks[indexPath.row].name
cell.NotesLabel.text = taskMgr.tasks[indexPath.row].note
cell.selectionStyle = .none
return cell
}
func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
func tableView(_ willDisplayforRowAttableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.backgroundColor = UIColor(red: 64/255.0, green: 67/255.0, blue: 68/255.0, alpha: 0)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if (editingStyle == UITableViewCellEditingStyle.delete) {
// handle delete (by removing the data from your array and updating the tableview)
taskMgr.removeTask(indexPath.row)
tblTasks.reloadData()
}
}
// EXPAND CELL ON CLICK
// Global Variables/Constants
var selectedCellIndexPath: NSIndexPath?
let selectedCellHeight: CGFloat = 88.0
let unselectedCellHeight: CGFloat = 44.0
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
self.tblTasks.rowHeight = UITableViewAutomaticDimension
if selectedCellIndexPath == indexPath as NSIndexPath? {
return selectedCellHeight
}
return unselectedCellHeight
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if selectedCellIndexPath != nil && selectedCellIndexPath == indexPath as NSIndexPath? {
selectedCellIndexPath = nil
} else {
selectedCellIndexPath = indexPath as NSIndexPath?
}
tableView.beginUpdates()
tableView.endUpdates()
if selectedCellIndexPath != nil {
// This ensures, that the cell is fully visible once expanded
tableView.scrollToRow(at: indexPath as IndexPath, at: .none, animated: true)
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
I'm open to any help and insight. Thank you very much.
Upvotes: 3
Views: 2868
Reputation: 17152
You need to set an Outlet to your UITableView
and set the rowHeight
parameter to UITableViewAutomaticDimension
. Also you need set the estimatedRowHeight
to a value fitting your needs. This way the size of the Cell will fit the size of its content.
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = 55
tableView.rowHeight = UITableViewAutomaticDimension
}
For this to work, you need to set the Autolayout Constraints for every element of your Cell.
Working with Self-Sizing Table View Cells
In iOS, you can use Auto Layout to define the height of a table view cell; however, the feature is not enabled by default.
Normally, a cell’s height is determined by the table view delegate’s
tableView:heightForRowAtIndexPath:
method. To enable self-sizing table view cells, you must set the table view’srowHeight
property toUITableViewAutomaticDimension
. You must also assign a value to theestimatedRowHeight
property. As soon as both of these properties are set, the system uses Auto Layout to calculate the row’s actual height.Additionally, try to make the estimated row height as accurate as possible. The system calculates items such as the scroll bar heights based on these estimates. The more accurate the estimates, the more seamless the user experience becomes.
Upvotes: 3