I have a UItableViewController and want the row height to adapt to the text in the UITextView. If I use this code in viewDidLoad it makes the height of the rows too small to hold the text:
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 50
The only way I can find to adjust the size is by changing the Table View Row Height in the StoryBoard. This changes every cell in the table view which is not what I want.
Does anyone have a suggestion about what I am missing?
This is my working code:
override func tableView(tableView: UITableView,
heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
var text:String
if indexPath.section > 0 {
text = switchNameArray [indexPath.row]
} else {
text = viewDescription
}
return calculateHeight(text)
}
func calculateHeight (text:String) -> CGFloat {
if UIDevice.currentDevice().userInterfaceIdiom == .Pad
{
return CGFloat(count(text)+50) // iPad
} else {
return CGFloat(count(text)+30) // iPhone
}
}
There is a override method to change the height for each row.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 50
}
You can also create and If-Else condition if you want to make it bigger or smaller. Just return a number
You could try using:
func tableView(tableView: UITableView,
heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 100 //Whatever fits your need for that cell
}
You can get the cell with tableView.cellForRowAtIndexPath(indexPath) and make the height whatever you need it to be.
If you want it to adapt to the size of your content
get the current tableView frame then adjust the height
depending on the height of the content.
var frame = CGRect(origin: tableView.frame.origin, size: tableView.frame.size)
frame.size.height = tableView.contentSize.height
tableView.frame = frame
Related
I have a table view with a dynamic height of cells. Above the table is menu with buttons. When I click on the menu button, the data is loaded into the table. When data is loaded, I want to have an animation in a cell that changes the height of a cell. I wonder how this can be done?
Thanks for the help.
Swift 4
Create a boolean variable in your model for checking if your cell is expanded or not.
if you want to expand the cell as long as your label height you should connect you labels constraint to your contentView in all directions and set number of lines to 0 in your storyboard.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
details[indexPath.row].cellIsOpen = !details[indexPath.row].cellIsOpen
detailTableView.reloadData()
detailTableView.beginUpdates()
detailTableView.endUpdates()
detailViewHeightConstraint.constant = CGFloat(detailTableView.contentSize.height) // the height of whole tableView
UIView.animate(withDuration: 0.3) {
self.view.layoutIfNeeded()
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if details[indexPath.row].cellIsOpen {
return UITableViewAutomaticDimension // or any number you wish
} else {
return 60 // default closed cell height
}
}
}
Also you can place this two lines in your viewDidLoad() function:
detailTableView.estimatedRowHeight = 60
detailTableView.rowHeight = UITableViewAutomaticDimension
I'm trying to hide a specific cell in my table view?
private var yourDataSource = [AccountData.AllTasksDB] //A Json Array originally
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
var rowHeight:CGFloat = 72
//AccountData.AllTasksDB[indexPath.row]["importantvariable"]
if (self.yourDataSource[indexPath.row]["importantvarible"] == "0")
{
print("Cell is mine")
rowHeight = 0
}
else
{
print("Cell is not mine")
rowHeight = 72.0
}
return rowHeight
}
Can anyone tell me what I'm doing wrong? I thought it was looping through each cell and checking a value i've setup before hand. But it doesn't seem to want to access it.
I figured this would be more legible in an answer
fileprivate var yourDataSource = [YourObject]()
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if self.yourDataSource[indexPath].isMine == true {
return 0
}
else
{
return 72.0 //or whatever you like
}
}
You are accessing cell in the tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) method.
At this point the cell is not yet visible (or dequeued). If the cell is not visible, it will be nil, hence your error.
Try putting a break point at let cell = tableView.cellForRowAtIndexPath(indexPath) as! TableViewCellMyTasks and you'll see that it is nil.
I have a UITableView that is populated with custom cells which had created by Xib(autolayout).The cell consist of multiple labels images etc and size of size of changes according to response we get from api.I have been trying hard set height dynamically. I am using following methods.
func createTabelView ()
{
let nib = UINib(nibName: "DBEventCell", bundle: nil)
self.eventTabelVew.registerNib(nib, forCellReuseIdentifier: Constants.CELL_IDENTIFIER)
self.eventTabelVew.estimatedRowHeight = 200
self.eventTabelVew.rowHeight = UITableViewAutomaticDimension
self.eventTabelVew.separatorStyle = .None //UITableViewCellSeparatorStyle.SingleLine;
self.eventTabelVew.separatorColor = UIColor.clearColor();
self.eventTabelVew.backgroundColor = UIColor.whiteColor();
self.eventTabelVew.setNeedsLayout()
self.eventTabelVew.layoutIfNeeded()
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return UITableViewAutomaticDimension
}
func tableView(tleView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
but this not working.Please do help as I am struck last from last few days.
Thanks in advance
I think you don't need this function
func tableView(tleView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
also you should check your cell autolayout constrains and adjusting properties of UI components to make it contract or expand with content also check this tutorial
https://www.appcoda.com/self-sizing-cells/
I want to dynamically change the height of the cell such that the image fills the imageView in the width and the image maintains the aspect ratio.
I am trying to do this using UITableViewAutomaticDimension. Based on tutorials available online, this seemed to be a straightforward task. But in my case, the height of the cell doesn't adjust to perform this task. Either the image fills with aspect ratio leaving a lot of width space empty or fills the width but clips the part of the image vertically. I made sure there are leading, trailing, top and bottom constraints with respect to the cell view and also the tableView.rowHeight = UITableViewAutomaticDimension and table.estimatedRowHeight is set in viewDidLoad. I have uploaded the project at this link. Could someone please suggest what could I be missing here?
Link to GitHub
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var picTableView: UITableView!
let reuseidentifier = "dynamicCellTableViewCell"
let images = [UIImage(named: "feedImage1"), UIImage(named: "feedImage2"), UIImage(named: "feedImage3")]
override func viewDidLoad() {
super.viewDidLoad()
picTableView.rowHeight = UITableViewAutomaticDimension
picTableView.estimatedRowHeight = 1000
}
// MARK: Table View Data Source
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return images.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(reuseidentifier, forIndexPath: indexPath) as! DynamicCellTableViewCell
cell.displayImageView.image = images[indexPath.row]
return cell
}
}
I figured the solution. UIImageView when used with UITableViewAutomaticDimension only looks for the UIImage's true width and height as the size. So UIImageView adjusts its height to respond to UIImage's original height and not the scaled height for scaled width (aspectFit) to match layout constraint.
So trick is to first change the width and height of the image to match the width and height that you need in the cell. Rest of the job will be done by UITableViewAutomaticDimension. Below is the updated cellForRowAtIndex function that works now. Thanks all for giving your inputs.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(reuseidentifier, forIndexPath: indexPath) as! DynamicCellTableViewCell
let image = images[indexPath.row]!
let newWidth = cell.displayImageView.frame.width
let scale = newWidth/image.size.width
let newHeight = image.size.height * scale
UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight))
image.drawInRect(CGRectMake(0, 0, newWidth, newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
cell.displayImageView.image = newImage
return cell
}
You need implement next method for UITableViewController:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 1000.0;
}
Inside the method, you must know what dimension will have each cell. You must know in advance what height will have each cell.
For example, you could create an array of CGFloat saving the height will have each row, and when height change, you can update this position in array and execude tableView.reloadData().
var arrayHeight:CGFloat?
//Now fill array with height of each cell
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return arrayHeight[indexPath.row];
}
cell.updateConstraintsIfNeeded()
cell.setNeedsUpdateConstraints()
add these two lines in the cellForRowAtIndexPath delegate method
And make sure that top, bottom, right, left, constraints are set in the storyboard
Im trying to set the height of a static UITableViewCell IBOutlet in Swift. Is this possible? I have found answers to how to change all cells in a tableview, but I just want to change this one and keep the rest as they are sized in the IB.
I've tried this:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.section == 1 && indexPath.row == 1 {
return CGFloat(screenSize.width)
}
else{
return UITableViewAutomaticDimension
}
}
To set the height dynamically on a static TableViewCell, you have to indeed set it in heightForRowAtIndexPath. Here is one implementation to change the second row in the first section:
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath.section == 0 && indexPath.row == 1 {
// Here return a number for the height you desire
return CGFloat(100)
}
else {
return UITableViewAutomaticDimension
}
}
Here are a few pointers that might be relevant to your situation. Please disregard them if they where done on purpose in your code..
The height for the cell was set to the width of the screen, it might be worthwhile to check if that was intended. Also please remember that both sections and rows start at index 0 and not at index 1.