How to set dynamic height of custom UITabelview cell in swit - iphone

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/

Related

Changing the height of cell depending on text height

I want to show a tableView with dynamic cell height. I found a way to change the height of my prototype cell in a tableView manually using this code. In this case the height is 400.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return CGFloat (400)
}
In my cell the first part with the username (green and red) and the last part with the likes (yellow) has a fixed height with for example 60.
The height of the part in the middle (blue) should change depending on the text. So how can I do that?
I tried to get the label height with this.
override func awakeFromNib() {
super.awakeFromNib()
userComment.sizeToFit()
print(userComment.bounds.size.height)
}
But this always shows me 18. My aim is to use the first code above and return CGFloat ( 60 + 60 + dynamic label/userComment height)
This is how my tableView looks like.
extension ViewComments: UITableViewDataSource {
func tableView (_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return table.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
let video: importComment
video = table[indexPath.row]
cell.userName.text = video.userName
cell.userGroup.text = poiNavigationName.title
cell.userComment.text = video.userComment
cell.userTime.text = "\(video.userTime!)"
cell.userLikes.text = "\(video.userLikes!)"
cell.userName.text = video.userName
cell.commentId.text = video.commentId
cell.kommentarCount.text = "\(video.kommentarCount!)"
cell.buttonAction = { [unowned self] in
let selectedIndexPath = table[indexPath.row].commentId!
ViewComments.commentIDNew = selectedIndexPath
}
return cell
}
/*
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return CGFloat (400)
}*/
}
Updated Picture after removing heightForRowAt and awakeFromNib
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return CGFloat (400)
}
instead of using a hard coded value you can use a dynamic height.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
UITableView.automaticDimension
}
https://developer.apple.com/documentation/uikit/uitableview/1614961-automaticdimension
It seems to me you're describing something like this:
That's done entirely with the internal autolayout constraints of the prototype cell. You should not attempt to do this manually by returning a specific height for each cell; just let the runtime do it for you. It knows how to do this a lot better.
I solved it not following this tutorial and it works great. Tutorial

Hide a specific cell in my table

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.

swift tableview image and label

I can't seem to figure how to have a tableview that contains a subject, body and image so that if there is not an image to have the subject and body together. see imageauto lay with table prototype
I would like the subject and body together when there is an image in the database and then if there is an image, then subject image body
pin the labels to the top and bottom of the cell. When you don't have an image you set the imageView.isHidden = true. You also return the regular cell height minus the imageView.frame.size.height in UITableViewDelegate.tableview(_:heightForRowAt:).
If you don't like approach just make two different tableViewCells and deque the one with the image when you have an image and the one without the imageView when you don't have an image.
You can do this in your dataSource methods for the tableview. Something like this should work:
//Model:
var model = [Stuff]
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "myprototype", for: indexPath)
cell.subjectLabel.text = model[indexPath.row].subject
cell.bodyLabel.text = model[indexPath.row].body
//assuming the image is an optional
if let image = model[indexPath.row].image {
cell.imageView.image = image
}
return cell
}
You might have to set the autolayout constraints for the imageView to have a low compression resistance.
You might also want to make the cells resize by implementing the following in the UITableViewDelegate methods:
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}

Swift: How to animate the rowHeight of a UITableView?

I'm trying to animate the height of tableViewCell rows by calling startAnimation() inside the tableView function:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! TableViewCell
tableView.rowHeight = 44.0
startAnimation(tableView)
return cell
}
//MARK: Animation function
func startAnimation(tableView: UITableView) {
UIView.animateWithDuration(0.7, delay: 1.0, options: .CurveEaseOut, animations: {
tableView.rowHeight = 88.0
}, completion: { finished in
print("Row heights changed!")
})
}
The result: The row height does change but without any animation occurring. I don't understand why the animation doesn't work. Should I perhaps define some beginning and end state somewhere?
Don't change the height that way. Instead, when you know you want to change the height of a cell, call (in whatever function):
self.tableView.beginUpdates()
self.tableView.endUpdates()
These calls notify the tableView to check for height changes. Then implement the delegate override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat, and provide the proper height for each cell. The change in height will be animated automatically. You can return UITableViewAutomaticDimension for items you don't have an explicit height for.
I would not suggest doing such actions from within cellForRowAtIndexPath, however, but in one that responds to a tap didSelectRowAtIndexPath, for example. In one of my classes, I do:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if indexPath == self.selectedIndexPath {
self.selectedIndexPath = nil
}else{
self.selectedIndexPath = indexPath
}
}
internal var selectedIndexPath: NSIndexPath? {
didSet{
//(own internal logic removed)
//these magical lines tell the tableview something's up, and it checks cell heights and animates changes
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if indexPath == self.selectedIndexPath {
let size = //your custom size
return size
}else{
return UITableViewAutomaticDimension
}
}

How to make the height of tableviewcell self-adaption to the text-label in it?

I am creating a TableViewController, now there's some cells in it, the longth of texts in these cells are not the same, so I wanna make the height of the cells self-adaption to the text-label.
I was thinking to creat the label first, then set the height of cell to fix it, but it seems not work, here is the code.
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! FuckGFWQATableViewCell
return cell.question.bounds.height
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("fuckGFWQATableViewCellId", forIndexPath: indexPath) as! FuckGFWQATableViewCell
cell.question.numberOfLines = 0
cell.question.text = fuckGFWQuestions[indexPath.section]
return cell
}
But when the heightForRowAtIndexPath called, the label was not exist. What should I do?
With iOS8 you can use self sizing cells in UITableView.Checkout here. You do not need to calculate your UILabel's height and set your cell. You just need to :
tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension