I am trying to set height of UILabel dynamically in the UITableView. During the launch height update is not reflected but as soon as I scroll down and scroll up back, update can be seen.
At Launch
After Scroll down and Scrolling back up again - This what I need. See the change in text in front of player icon. I need the complete text at launch itself.
Here is the code that I am trying to use:
- (void) updateMessageTextForRow:(long)row ofCell:(ESGameStreamCellView *)cell
{
NSString *item = _gameFeedItems[row];
NSString *title = item ?: NSLocalizedString(#"[No Title]", nil);
cell.message.preferredMaxLayoutWidth = cell.message.bounds.size.width;
// Update message label height
CGSize maximumLabelSize = CGSizeMake(296, FLT_MAX);
CGSize expectedLabelSize = [title sizeWithFont:cell.message.font
constrainedToSize:maximumLabelSize
lineBreakMode:cell.message.lineBreakMode];
//adjust the label the the new height.
CGRect newFrame = cell.message.frame;
newFrame.size.height = expectedLabelSize.height;
cell.message.frame = newFrame;
NSLog(#"Message = %#, Height: %f", title, cell.message.frame.size.height);
}
During Custom TableCellView Initialization
- (void)awakeFromNib {
// Initialization code
self.backgroundColor = [UIColor clearColor];
_message.lineBreakMode = NSLineBreakByWordWrapping;
_message.numberOfLines = 0;
}
Code for the row height
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// Currently fixed height. Will be calculating dynamic height after adjusting the views.
return 300;
}
Are you using autoLayout ? I highly suspect that your constraints aren't set up properly: the UIImageView top should by tied with the titleLabel's bottom.
Also, you should use the new property for dynamic row : rowHeight and estimatedRowHeight.
You are getting the correct height after the cell's reuse : set the preferredMaxLayoutWidth property in the viewDidLayoutSubviews inside your custom cell class.
firstly, you should understand of the working flow of tableview delegate in objective c. Your cell height & position will be fixed after init. that's why you have to define each row's height in
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// Currently fixed height. Will be calculating dynamic height after adjusting the views.
return 300;
}
From this point forward, your cell's height will be fixed, even if you re-config the frame.
The best practice is some article called "Dynamic height tableview cell" and you can easily find it here
http://www.raywenderlich.com/87975/dynamic-table-view-cell-height-ios-8-swift
I learn on above article (thanks for Joshua Greene) and re-write it to another library allow you to make a dynamic tableview easily. You can find it here
https://github.com/EugeneNguyen/XBMobile
it's not too perfect, but hope that if can help.
Related
This question already has answers here:
Using Auto Layout in UITableView for dynamic cell layouts & variable row heights
(28 answers)
Closed 6 years ago.
Hi in my application i have a requirement to display prodcuts with description in tablview. For achieving this i added two satckviews on tablview cell content view. Both stackviews holds labels and one label have a prodcut name and another one have description. At app launch the app cell height is 100 by default, but when ever i select cell i want to show complete description in cell along with product name i mean need to change cell height.Can anyone please let help me how to achieve this.How to change cell height dynamically. Please help me.
I tried below approach it shows more description in stack view label but cell height is not getting change. So unable to see total description.
cell.productDescription.numberOfLines=50;
cell.productDescription.lineBreakMode=NSLineBreakByCharWrapping;
Best way to use Constraint for your application. So you don't have to manage heighforCell. If you are going to coding part then you have to find out height of text and then you need to set in heightForRowAtIndexPath method.
Here is the code to get height from string:
-(float )getHeightForText : (NSString *)strText
{
UILabel *lbl = [[UILabel alloc] init];
CGRect rect;
rect.origin = CGPointZero;
float width = YOUR_LABEL_WIDHT
rect.size = CGSizeMake(width, 3000);
lbl.font = MESSAGE_TEXT_FONT;
lbl.frame = rect;
lbl.text = strText;
lbl.numberOfLines = 1000;
[lbl sizeToFit];
float height = lbl.frame.size.height;
return height;
}
Write below code in your heightForRowAtIndexPath method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [self getHeightForText:YOUR_TEXT];
}
Use UITableViewDelegate Method
#pragma mark - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
I have to show the list details in UITableview. But the listing is small for some cells and large/medium height for some other cells. (Like facebook feed) So Tableview have different height for each cell. How can i achieve this?
The list contains,
imageview,2 labels, textview (Label and textview lengths also increased based on its content. It will also affect the tableview cell height). So any help to achieve this would be greatful.
Thanks.
Create your cells with their own .xib. Add the labels, textview imageviews etc as you want. Make sure to pin all them with constraints horizontally and vertically to the leading/trailing/top and bottom of the cell.
Now the trick is to tell autolayout to layout the contentView of the cell, and return the minimum height to fit its content. Since heightForRow is executed before the cell is loaded in cellForRow, we need to use a fakeCell to calculate the height.
To do this lets say, in our controller, we have a tableView showing cells of class DetailsTableViewCell with a nib created for it DetailsTableViewCell.xib :
1) Create a #property in your controller for a fakeCell.
#property (nonatomic, strong) DetailsTableViewCell *fakeCell;
2) In viewDidLoad, initialize it from them nib:
self.fakeCell = [[NSBundle mainBundle] loadNibNamed:NSStringFromClass:#"DetailsTableViewCell" owner:nil options:nil].firstObject;
3) In heightForRowAtIndexPath:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
//grab fakeCell, style it with the data you want
[self.fakeCell styleWithDetails:self.details];
//and calculate the minimum height required to fit all content
return [self minimumCellHeightToSatisfyConstraints:self.fakeCell];
}
-(CGFloat)minimumCellHeightToSatisfyConstraints:(UITableViewCell *)cell {
//Makes sure cell's width is equal to tableView's width (can be wrong since they are in separated nibs)
cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.tableView.bounds), CGRectGetHeight(cell.bounds));
//Force autolayout to recalculate all subview's frames
[cell layoutIfNeeded];
//Get the minimum height required for the cell to fit all its content
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
return height;
}
Important: If you forget to pin all subviews in the .xib vertically from top to bottom to the cell, calling systemLayoutSizeFittingSize:UILayoutFittingCompressedSize will return 0 and won't work.
#define CELL_MARGIN 10.0f
-(CGFloat)heightForTableView:(NSString*)text widthOfTableview:(CGFloat)tableViewWidth{
CGSize constraint = CGSizeMake(tableViewWidth - (CELL_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 44.0f);
return height + (CELL_MARGIN * 2);
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self heightForTableView:cell.titleLabel.text widthOfTableview:CGRectGetWidth(tableView.frame)];// cell.textlable.text is your lable.text
}
This code might helps you :)
I have used the following code to dynamically change the row height in ios. But the height is too high. I dont know where i made mistake. My code is as follows:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(!self.customCell){
self.customCell = [self.goalDetailsTableview dequeueReusableCellWithIdentifier:#"GoalDetailsCell"];
}
NSMutableDictionary *cellData = [self.databaseCall transactionFromDatabase:indexPath.row goalId:self.goalId andStageId:self.stageId];
//Cell Layout
self.customCell.tipsDescription.text = [cellData objectForKey:#"tipsDescription"];
[self.customCell.tipsDescription sizeToFit];
//Height of cell
float height = (CGRectGetMaxY(self.customCell.tipsDescription.frame) + 20);
return height;
}
Note: tipsDescription is a UILabel inside the UIView which is kept inside the UITableViewCell.
You need to calculate your text height and based on it have to set cell height (yes, its going to be little mind expensive but at last you'll be happy!). Here's the one solution for this, Replacement for deprecated sizeWithFont: in iOS 7? and if you want some more info, Calculating number of lines of dynamic UILabel (iOS7) and this too UITableViewCell with UITextView height in iOS 7? (I know its not for UITextView but you can consider it with UILabel).
With iOS 8 we have self sizing table view cells. With it, there is no need to even implement heightForAtIndexPath.
Step 1) Set up constraints for your table cell
Step 2) In viewDidLoad:
self.tableView.estimatedRowHeight = 100.0; //or whatever value you need
self.tableView.rowHeight = UITableViewAutomaticDimension;
And that's it. I would also mention a few of us have ran into an issue where you might need to reload the table view's data in viewDidAppear.
I have a UITextView inside a UITableViewCell. I am attempting to set the height of the UITextView it based on the content size. Inside my cellForRowAtIndexPath method I have:
CustomCell *cell = (CustomCell *) [tableView dequeueReusableCellWithIdentifier:#"CustomCell"];
....
cell.text.text = textString; // cell.text is the UITextView
CGRect frame = cell.text.frame;
frame.size.height = cell.text.contentSize.height;
cell.text.frame = frame;
return cell;
There are other objects on the custom cell, but nothing has constraints. The interesting thing is that when the table view is first loaded, the UITextView does not resize. However, when another cell is loaded by scrolling down or back up, the UITextView resizes to the correct height based on the above code. Why isn't the initial table loading correctly.
The UITextView has a default width and height size. Let me know if I can add more details. I am not implementing heightForRowAtIndexPath, but the testing I am doing has not exceeded the default cell heights so this should not matter anyways.
Did you log the value of cell.text.contentSize.height ?
At that moment you don't get the correct value, I think you should set the height on the following UITableView callback:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
Try to add [cell.text layoutIfNeeded] before calling cell.text.contentSize
The contentSize will be unknown by the UITextField until it has been drawn. Calling layoutIfNeeded should force the computation of layout size.
If finaly made it work with this, try it
cell.text.attributedText = [[NSAttributedString alloc]initWithString:textString];
float textViewWidth = cell.text.frame.size.width;
[cell layoutIfNeeded];
cell.text.contentSize = [cell.text sizeThatFits:CGSizeMake(textViewWidth, FLT_MAX)];
[cell.text sizeToFit];
I am trying to create multi-line dynamic UILabels in UITableViewCells. I have a custom UITableViewCell that has a 'comment' label. The cell and the label are created in storyboard.
I can compute the heights of the UITableViewCells properly based on the multi-line data to be stored in the UILabel (using heightForRowAtIndexPath). However, my problem lies in the actual UILabel content. The UILabel content will display only 1 line of data on table load. However, once a cell containing multiline UILabel data moves offscreen and comes back on screen, the multi-line data appears properly in the UILabel with multiple lines. Is there any way to fix this so that the multi-line data appears properly on table load?
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cCell = (CustomCell *)cell;
MyObject = [myArray objectAtIndex:indexPath.row];
cCell.commentLabel.frame = CGRectMake(65.0f, 28.0f, 243.0f, 200.0f);
cCell.commentLabel.text = MyObject.multi_line_text_data;
cCell.commentLabel.adjustsFontSizeToFitWidth = NO;
cCell.commentLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
cCell.commentLabel.font = [UIFont systemFontOfSize:13.0];
cCell.commentLabel.lineBreakMode = NSLineBreakByWordWrapping;
cCell.commentLabel.numberOfLines = 0;
[cCell.commentLabel sizeToFit];
}
Thanks!
Since you're doing this in the storyboard, you can set the necessary label properties there (lineBreakMode and number of lines). Just give the label a specific width constraint and constraints to the top, bottom, and left sides of the cell. Then, in code use sizeWithFont:constrainedToSize:lineBreakMode: in heightForRowAtIndexPath: to calculate the appropriate height for the cell based on the content of the label -- the label, because of its constraints, will expand along with the cell to the proper size. Something like this:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGSize rowSize = [self.theData[indexPath.row] sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(260, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping];
return rowSize.height + 30;
}
Here, 260 was the width I gave my label in IB, and the 30 is a fudge factor (determined empirically) to account for padding above and below the label.
I met the same problems. Unchecking Autolayout can fix it.