Swift/Objective C - Simple Way to Dynamically change TableView Cell height
In my table view cell break first line and third line, every label will dynamic
Add Constraints to Image View (top, Leading, trailing, Height)
Don't Add Bottom Constraints
Add Constraints to Each label (top, Leading, trailing, Bottom)
Add Constraints to last label (top, Leading, trailing, Bottom)
Set each label
Number of Line = 0
Line Breaks mode = word warp
Table View Datasource and Delegate Methods
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("PropertyListCell", forIndexPath: indexPath) as UITableViewCell!
imgProperty = viewBg.viewWithTag(111) as! RemoteImageView
lblPropertyName = viewBg.viewWithTag(112) as! UILabel
lblPrice = viewBg.viewWithTag(113) as! UILabel
lblAddress = viewBg.viewWithTag(114) as! UILabel
lblAreaPerSquare = viewBg.viewWithTag(115) as! UILabel
imgProperty.imageURL = NSURL(string: "Image Url")
lblPropertyName.text="Jai Maharashtra Apartment"
lblPrice.text="Rs. 900 - 10000"
lblAddress.text="411041,Maharashtra Sadan, Pune, Maharashtra , India" // just address changed.
lblAreaPerSquare.text="500 Square Meter"
cell.selectionStyle = UITableViewCellSelectionStyle.None
return cell
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return UITableViewAutomaticDimension
}
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return 44.0
}
Now All labels are Dynamic
Swift - 3.0
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
var height:CGFloat = CGFloat()
if indexPath.row == 0 {
height = 80
}
else if indexPath.row == 1 {
height = self.view.frame.size.height - 80 - 44 - 64
print(height)
}
return height
}
Related
I need to change cell height depend on the message label text
Cell.Xib Design img
for message label i have given constraints
trailing = leading = top = 10, height => 30 (greater then or equal to height)
and line count = 0
now label is increasing but cell is not increasing why?
o/p
o/p img
code:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return msgArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MessageDetailsTableViewCell", for: indexPath) as! MessageDetailsTableViewCell
self.tableView.separatorStyle = .none
cell.msgLabel.text = msgArray[indexPath.row]
cell.nameLabel.text = nameArray[indexPath.row]
cell.timeLabel.text = timeArray[indexPath.row]
cell.picImageview.image = UIImage(named: "icon12")
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100//UITableView.automaticDimension
}
if i give heightForRowAt = UITableView.automaticDimension then nothing comes, if i fixed its height to 100 then cell is not increasing, why? please do help
You can go simple with two number of steps:
1. heightForRowAt Method:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
2. UILabel Property
yourLabel.numberOfLines = 0 // or you can set numberOfLines from storyBoard.
For this, you need to follow the below steps.
Step1: Set the constraint of your label as leading, trailing, top and bottom. Set bottom constraint to greater than equal to.
Step 2: Set label's number of lines to 0.
label.numberOfLines = 0
Step 3: In ViewDidLoad Function
self.tableView.rowHeight = UITableView.automaticDimension
self.tableView.estimatedRowHeight = 150
I got two cells in my UITableView. One is a custom UITableViewCell and the other is a cell with a UITextView inside and called the type TextViewCell.
Because they are static I the cells are loaded in viewDidLoad method from a xib:
textCell = Bundle.main.loadNibNamed(String(describing: TextViewCell.self),
owner: self, options: nil)?.first! as! TextViewCell
ratingCell = Bundle.main.loadNibNamed(String(describing: RatingCell.self),
owner: self, options: nil)?.first! as! RatingCell
Now I try to change the height with the the heightForRowAt delegate:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 1 {
return textCell.textView.contentSize.height
}
return ratingCell.ratingView.frame.height
}
I disabled scrolling on the UITextView but the cell is not resizing properly. In fact the cells gets smaller.
The constraints of the TextViewCell look like this:
Any suggestions?
I think you need to use self-sizing UITableViewCell. Replace your current implementation of heightForRowAt with the following:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Now height of cells in your UITableView object will be calculated automatically based on constraints.
Also, add some estimated value for row height:
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 100.0 // You can set any other value, it's up to you
}
Now you will see that the UITextView view fills the whole UITableViewCell cell.
You should get the height of UITextView in heightForRowAt and return this height as cell height. See example below
let lblDescLong = UITextView()
lblDescLong.textAlignment = .left
lblDescLong.text = “your text for text view”
lblDescLong.font = YourFont(size: 12)
let newSize = lblDescLong.sizeThatFits(CGSize(width: widthForTextView, height: CGFloat.greatestFiniteMagnitude))
return newSize.height
I have a expandable tableView, in which when i expand a section, than there are three cell. On firth Cell there is only name and in second cell. It have a big content. Now I want to auto adjust this label height and width according to content.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tblView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell
let dataArrayTblView = dataArrayForTableView
let titleName = dataArrayTblView.valueForKey("name")
let dueDate = dataArrayTblView.valueForKey("deadlinedate")
let description = dataArrayTblView.valueForKey("description")
cell.titleLabel.text = titleName[indexPath.row] as AnyObject! as! String!
cell.dueDateLabel.text = dueDate[indexPath.row] as? String
cell.descriptionLabel.text = description[indexPath.row] as? String
cell.descriptionLabel.sizeToFit()
cell.textLabel?.backgroundColor = UIColor.clearColor()
cell.selectionStyle = .None
return cell
}
But not getting complete content
Try to set this. It will automatically adjust the height of the row for you. If it is not working, then you have something wrong with your constraints inside your storyboard.
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 40
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
You should use UITableViewAutomaticDimension as row height something like,
// this should be set in viewDidload
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 140
for that you must use autolayout and should set proper constraints to your label in cell.
Constraint should be in linear chain, I mean your label's top and bottom both constraint must be set and your label should resize according to content so your cell will resize accordingly!
You can refer Self-sizing Table View Cells by Raywenderlich !
Put below in viewDidLoad and set autolayout as per below screenshots.
tblview.rowHeight = UITableViewAutomaticDimension
tblview.estimatedRowHeight = 44
Screenshot 1
Screenshot 2
Screenshot 3
Screenshot 4
Use heightForRowAtIndexPath method to adjust height of row. Calculate
size of string with boundingRectWithSize this method. example:
Try This:
if let YOUR_STRING:NSString = str as NSString? {
let sizeOfString = ns_str.boundingRectWithSize(
CGSizeMake(self.titleLabel.frame.size.width, CGFloat.infinity),options: NSStringDrawingOptions.UsesLineFragmentOrigin, attributes: [NSFontAttributeName: lbl.font], context: nil).size
}
How to set view height programmatically? I have this code:
cell.viewMain.frame = CGRectMake(cell.viewMain.frame.origin.x, cell.viewMain.frame.origin.y, cell.viewMain.frame.size.width, 65.0)
But that is not working.
UPDATE:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("updateCell", forIndexPath: indexPath) as! UpdateCell
if self.data[indexPath.row] == "b" {
tbUpdate.rowHeight = 85
cell.viewMain.frame = CGRectMake(cell.viewMain.frame.origin.x, cell.viewMain.frame.origin.y, cell.viewMain.frame.size.width, 65.0)
}else{
tbUpdate.rowHeight = 220
cell.viewMain.frame = CGRectMake(cell.viewMain.frame.origin.x, cell.viewMain.frame.origin.y, cell.viewMain.frame.size.width, 200.0)
}
return cell
}
TableView cells have their height set by the table view.
You need to implement UITableViewDelegate tableView:heightForRowAtIndexPath:.
first, rowHeight changes the height of all rows in your table. if you want specific height for specific rows, implement tableView:heightForRowAtIndexPath: method. remove tbUpdate.rowHeight in your code first.
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
var cellHeight:CGFloat = CGFloat()
if indexPath.row % 2 == 0 {
cellHeight = 20
}
else if indexPath.row % 2 != 0 {
cellHeight = 50
}
return cellHeight
}
You can try using autolayout to create a height constrait and then connect the constraint to an outlet. Then set the constant for that constraint,
var y: Float
if x==0{ //some condition
y = 10
}else if x==1{ //some condition
y = 20
}
cell.viewMainHeightConstraint.constant = y
cell.view.layoutIfNeeded()
Put this in your cellForRowAtIndexPath
Edit : I misinterpreted the question as asking for another view within the cellView, if so the delegate method heightForRowAtIndexPath is indeed correct as stated in the above answer.
An example:
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
if x == 0{
return 100.0 //Choose your custom row height
} else {
return 50
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
var height:CGFloat = CGFloat()
if indexPath.row == 0 {
height = 80
}
else if indexPath.row == 1 {
height = self.view.frame.size.height - 44 - 64 // 44 is a tab bar height and 64 is navigationbar height.
print(height)
}
return height
}
This is my layout.The Label's top to the ContentView's top is 58pt.The numberOfLine of the Label is 0.So it can Enter automatically.
And I want the Height of every cell is 58.0+10.0+the height of label.
I have tried this code.
TV.estimatedRowHeight = 68
TV.rowHeight = UITableViewAutomaticDimension
But didn't work.
And then tried this code.
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! CommentDetailCell
return 68.0 + cell.Comment.frame.size.height
}
Didn't work again.
And then try this!To create a array to store the height of every cell's labelHeight.
var CommentHeightA:[CGFloat] = [60.0,60.0,60.0,60.0]
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell:CommentDetailCell = tableView.dequeueReusableCellWithIdentifier("cell") as! CommentDetailCell
cell.UserImg.image = UIImage(named: UserImgA[indexPath.row])
cell.AtNum.text = AtNumA[indexPath.row]
cell.LikeNum.text = LikeNumA[indexPath.row]
cell.isLike.image = UIImage(named: isLikeA[indexPath.row])
cell.Comment.text = CommentA[indexPath.row]
CommentHeightA[indexPath.row] = cell.Comment.frame.size.height
return cell
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 68.0 + CommentHeightA[indexPath.row]
}
And :( all the ways above is failed.
So how can I get what I want?
Update:
I have added the bottom constraint and used the 1st way.
This is the result.Only the 1st row has a appropriate height.
You need to add a bottom constraint from the comment label to the content view. Then add the following code:
TV.estimatedRowHeight = 68
TV.rowHeight = UITableViewAutomaticDimension
It will work,