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

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

Related

UICollectionView inside a UITableViewCell — dynamic height calculate isn't correct

I have a dynamic height collection view in table view cell. I used the approach #Igor in this topic.
UICollectionView inside a UITableViewCell -- dynamic height?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DraftCustomerTableViewCell", for: indexPath) as! DraftCustomerTableViewCell
cell.data = notificationDraftListViewData[indexPath.section]
cell.frame = tableView.bounds
cell.collectionView.reloadData()
cell.collectionViewHeightConstraint.constant = cell.collectionView.collectionViewLayout.collectionViewContentSize.height
cell.layoutIfNeeded()
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
dict[indexPath] = cell.frame.size.height
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return dict[indexPath] ?? CGFloat(450)
}
The issue is when I expand the tableview section first time, the cell's height is not calculate right. After expanding first time, the collectionView's height can been calculated correctly. I try to let my data[0].isExpand is true without taping the button and find the table view's cell height is correct. Please see the demo. Is there some approach can avoid this issue? thanks.
Demo: https://youtu.be/YJCJChCU0wQ

Tableview set row height dynamically based on content in swift?

I am struck in setting tableview cell row height in swift , On scrolling the row height is changing, please check the screen shot.
For the first time its scrolling perfect on scrolling multiple times the height is not proper. I am using too many custom tableview cells
In viewDidLoad
I added this
self.tableView.rowHeight = UITableViewAutomaticDimension
and also added these delegate methods.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return UITableViewAutomaticDimension
}
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return UITableViewAutomaticDimension
}
Can anyone guide me to achieve this in proper way.

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
}

How to set dynamic height of custom UITabelview cell in swit

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/

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
}
}