I know this is going to be a stupid daft simple question but I'm going round in circles.
I have several strings which i want displaying in a uitableview. Some of these strings are very long. I have previously asked how to calculate the cell height, and choose the following answer:
- (CGFloat)cellHeightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellString = <YOUR MODEL OBJECT>;
NSDictionary *attributes = #{ NSFontAttributeName : [UIFont systemFontOfSize:16.0f] };
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc]
initWithString: cellString
attributes:attributes];
CGFloat width = self.tableView.frame.size.width - 32.0f;
CGRect frame = [attributedString boundingRectWithSize:CGSizeMake(width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin context:nil];
// Add some extra padding to the height
CGFloat height = frame.size.height + 16.0f;
return ceil(height);
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [self cellHeightForRowAtIndexPath:indexPath];
}
how can I get the number of lines required in the uitableview to display the strings.
The best way to actually calculate a cell height is to use a prototype cell for calculating the height.
Add a property to your interface extension:
#interface TableViewController ()
#property (nonatomic, strong) TableViewCell *prototypeCell;
#end
Then lazily load it:
- (TableViewCell *)prototypeCell
{
if (!_prototypeCell)
{
_prototypeCell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"Prototype"];
}
return _prototypeCell;
}
Change your -[tableView:cellForRowAtIndexPath:] method to use a -[configureCell:forRowAtIndexPath:] type pattern:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellId" forIndexPath:indexPath];
[self configureCell:cell forRowAtIndexPath:indexPath];
return cell;
}
-(void)configureCell:(TableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Set up you cell from your model
}
Now use this method to setup your prototype and then use the height of that for -[tableView:heightForRowAtIndexPath:]:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
[self configureCell:self.prototypeCell forRowAtIndexPath:indexPath];
[self.prototypeCell layoutIfNeeded];
CGSize size = [self.prototypeCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return ceil(size.height);
}
Related
I've tried plenty of answers on SO but nothing really worked. I'm probably doing something wrong so I need someone to point out what I'm doing wrong..
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"text : %#", self.cell.comment.text);
NSString *text = self.cell.comment.text;
CGFloat width = self.cell.frame.size.width;
UIFont *font = [UIFont fontWithName:#"HelveticaNeue" size:15];
NSAttributedString *attributedText =
[[NSAttributedString alloc] initWithString:text
attributes:#{NSFontAttributeName: font}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
CGFloat height = ceilf(size.height);
return height;
}
I get "NSInvalidArgumentException" with reason "NSConcreteAttributedString initWithString:: nil value" because self.cell.comment.text isn't getting anything by the time I set cell height but it does come through just not when heightForRowAtIndexPath gets called.
Many people have commented on that answer that this method works just fine so I guess I'm missing something?
Edit
I'm setting self.cell.comment.text here -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object{
static NSString *simpleTableIdentifier = #"cell";
self.cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (self.cell == nil) {
self.cell = [[CommentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
self.cell.comment.text = [object objectForKey:#"comment"];
[self.cell.comment sizeToFit];
return self.cell;}
Your problem as you already comment is that function heightForRowAtIndexPath is called before cells are populated.
For every cell that become visible it first call
get height of this cell
populate cell
So you know that
a) your text is not yet populated on the cell
b) some other text might be inside, because apple use reusable cells, so UITableView can grab some cell (with different text) and try to resize it and then populate it.
In your case it will grab some other text, resize cell to its size and then populate it with some other text that is (probably) different size then previous text.
But inside cell populations you set text from some business logic (maybe array?), and you can get same text in this method.
if cell population you call
cell.comment.text = [self.someArray getObjectAtIndex:index.row];
you call this in your heightForRowAtIndexPath method.
NSString *text = [self.someArray getObjectAtIndex:index.row];
I see your edit just call :
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"text : %#", self.cell.comment.text);
NSString *text = [object objectForKey:#"comment"];;
CGFloat width = self.cell.frame.size.width;
UIFont *font = [UIFont fontWithName:#"HelveticaNeue" size:15];
NSAttributedString *attributedText =
[[NSAttributedString alloc] initWithString:text
attributes:#{NSFontAttributeName: font}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
CGFloat height = ceilf(size.height);
return height;
}
ADDITION :
Tel say you would like to have cells like this :
-------------------------
| bla bla bla |
------------------------
| second longer text |
| over more line |
------------------------
You need to have texts bla bla and "second longer text over more line" somewhere saved.
Let say you have array with size 2.
NSArray * myTextArray = #[#"bla bla", #"second longer text over more line"];
and when populating cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object{
static NSString *simpleTableIdentifier = #"cell";
self.cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (self.cell == nil) {
self.cell = [[CommentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
self.cell.comment.text = [myTextArray objectAtIndex:indexPath.row];
[self.cell.comment sizeToFit];
return self.cell;
}
because heightForRowAtIndexPath is called before cellForRowAtIndexPath we need to check text from business (array) side and not visual.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"text : %#", self.cell.comment.text); // -> this is null because cell is not populated yet.
NSString *text = [myTextArray objectAtIndex:indexPath.row]; -> this is same text as we will take when populating cell and is not random.
CGFloat width = self.cell.frame.size.width;
UIFont *font = [UIFont fontWithName:#"HelveticaNeue" size:15];
NSAttributedString *attributedText =
[[NSAttributedString alloc] initWithString:text
attributes:#{NSFontAttributeName: font}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
CGFloat height = ceilf(size.height);
return height;
}
EXAMPLE :
#import "ViewController.h"
#interface ViewController ()
#property NSArray * myArray;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.myArray = #[#"Some short text",#"Some longer text that take some more space throw more lines",#"bfusdbfjdsfjs fj yfsdy fgsydu fyudsfy fyudsyu fdsy fuysdyuf ydsug fyu sdgyfgsuyff ius fhs fiusdhi ufdshu uifsd ufsdh hfiuds uifdsh fsduih ufdshu hfsd ifshui"];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 3;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *text = self.myArray[indexPath.row];
CGFloat width = 300;
UIFont *font = [UIFont fontWithName:#"HelveticaNeue" size:15];
NSAttributedString *attributedText =
[[NSAttributedString alloc] initWithString:text
attributes:#{NSFontAttributeName: font}];
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
CGFloat height = ceilf(size.height);
return height;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = #"cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
cell.textLabel.text = self.myArray[indexPath.row];
cell.textLabel.numberOfLines = 0;
return cell;
}
this example works.
In heightForRowAtIndexPath:
For width, I think you can fix it, and don't need this line:
CGFloat width = self.cell.frame.size.width;
For the comment text
NSString *text = self.cell.comment.text;
Try this
NSString *text = [object objectForKey:#"comment"];
Spent all day trying to figure this out and finally found out that the solution was super simple, I just needed to know how to use Parse better.
Thanks to Marko, I've learned how UITableView really works and that's great but the solution to my problem was a bit different.
As everyone suggested my problem was assuming that heightForRowAtIndexPath would get called after all cells are populated but I did not need an array to save objects or make any change. Parse apparently saves all retrieved objects before heightForRowAtIndexPath gets called and they're all in self.objects.
self.cell.comment.text = [self.objects objectAtIndex:indexPath.row];
And as Andy passionately suggested, I'm now using Auto-size UITableViewCell.
In your PFQueryTableViewController
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
PFObject *object = [self.objects objectAtIndex:indexPath.row];
if (object) {
NSString *commentString = [self.objects[indexPath.row] objectForKey:#"comment"];
NSLog(#"commentString : %#",commentString);
CommentCell *cell = [[CommentCell alloc] init];
cell.textLabel.text = commentString;
[cell setNeedsLayout];
[cell layoutIfNeeded];
self.height = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
self.height += 1;
}
return self.height;}
In your CustomCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.textLabel.numberOfLines = 0;
self.textLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-6-[bodyLabel]-6-|" options:0 metrics:nil views:#{ #"bodyLabel": self.textLabel }]];
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|-6-[bodyLabel]-6-|" options:0 metrics:nil views:#{ #"bodyLabel": self.textLabel }]];
}
return self;}
- (void)layoutSubviews{
[super layoutSubviews];
[self.contentView setNeedsLayout];
[self.contentView layoutIfNeeded];
self.textLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.textLabel.frame);}
This definitely works.
I've been trying to make a dynamic table view cell to use in a chat
You can see that actually im using a constant height for the cell(88) but if the text is longer, it will be awful
I'm using the font Muli and that's why I don't know how can I calculate the correct height.
here is my code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 88;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.comunidades count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = (UITableViewCell *)[self.tabla dequeueReusableCellWithIdentifier:#"DM_tab"];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"DM_tab" owner:self options:nil];
cell = (UITableViewCell *)[nib objectAtIndex:0];
}
NSDictionary *comunidad = [self.comunidades objectAtIndex:indexPath.row];
UILabel *textosender=(UILabel *) [cell viewWithTag:2];
textosender.text=[comunidad objectForKey:#"nombre"];
textosender.font = [UIFont fontWithName:#"Muli-Light" size:14];
UILabel *textomio= (UILabel *) [cell viewWithTag:3];
textomio.text=[comunidad objectForKey:#"nombre"];
textomio.font = [UIFont fontWithName:#"Muli-Light" size:14];
NSString *tipo=[comunidad objectForKey:#"sender"];
NSUserDefaults *defs=[NSUserDefaults standardUserDefaults];
if([tipo isEqualToString:[defs objectForKey:#"username"]]){
UIImageView* img = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"A_DM_fondo#2x.png"]];
[cell setBackgroundView:img];
textosender.hidden=YES;
textomio.hidden=NO;
NSString *detallemio=[comunidad objectForKey:#"mensaje"];
[textomio setText:detallemio];
}
else{
UIImageView* img = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"N_DM_fondo#2x.png"]];
[cell setBackgroundView:img];
textosender.hidden=NO;
textomio.hidden=YES;
NSString *detallemio=[comunidad objectForKey:#"mensaje"];
[textosender setText:detallemio];
}
return cell;
}
Thanks
Replace the 88 in the tableView:heightForRowAtIndexPath: method with the height you want the particular row to have, calculated using something like the boundingRectWithSize:options:attributes:context: method on NSString.
There is a NSTextField in a NSTableView.
The height of the text in the window resizing is increased.
but Not grow the cells in a table view.
In this case, the height of table view cell to alter how do you like?
in short, When resizing the size of the text view, I want to change the size of the cell.
like this: (Mac store)
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row;
{
KFCustomCellView *cellView = [tableView makeViewWithIdentifier:#"MainCell" owner:self];
NSString *comment = [[_commentList objectAtIndex:row]valueForKey:#"COMMENT"];
[cellView.comment setStringValue:comment];
float cellheight = [comment heightForStringDrawing:comment font:[cellView.comment font] width:self.view.frame.size.width * 0.8];
if (cellheight > cellView.comment.frame.size.height)
{
return (cellheight + 65);
}
return 90;
}
Use following approach the to resize cell height according to textview content :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *DataCellId = #"DataCell";
dataCell = (Cell *)[tableView dequeueReusableCellWithIdentifier:DataCellId];
if(!dataCell)
{
dataCell = [[[Cell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:DataCellId] autorelease];
}
dataCell.dataCellTextView.tag = indexPath.row;
dataCell.dataCellTextView.text =[yourDataArry objectAtIndex:indexPath.row];
return dataCell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
#define PaddingForTableRowHeight 24
NSString *text;
if([yourDataArry count] > indexPath.row)
{
text = [yourDataArry objectAtIndex:indexPath.row];
} else {
text = #"";
}
UIFont *dataFont = [UIFont boldSystemFontOfSize:16.0f];
CGSize textSize ;
if([UICommonUtils checkIfiOS7])
{
// For iOS7
textSize = [text boundingRectWithSize:CGSizeMake("YOUR CELL WIDTH", MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:#{NSFontAttributeName:dataFont} context:nil].size;
} else {
textSize = [text sizeWithFont:dataFont constrainedToSize:CGSizeMake("YOUR CELL WIDTH" - PaddingForTableRowHeight,MAXFLOAT)];
}
float textViewHeight = MAX(kDefaultCellHeight, textSize.height+PaddingForTableRowHeight);
return textViewHeight;
}
-(void)textViewDidBeginEditing:(UITextView *)textView
{
[self scrollToCursorForTextView:textView];
}
-(void)textViewDidEndEditing:(UITextView *)textView
{
if([yourDataArry count] > textView.tag)
{
[yourDataArry replaceObjectAtIndex:textView.tag withObject:textView.text];
}
}
- (void)textViewDidChange:(UITextView *)textView
{
dataUpdated =YES;
if([yourDataArry count] > textView.tag)
{
[yourDataArry replaceObjectAtIndex:textView.tag withObject:textView.text];
}
[self performSelector:#selector(dataReload) withObject:nil afterDelay:0.0];
[self scrollToCursorForTextView:textView];
}
-(void)dataReload
{
[self.tbl beginUpdates];
[self.tbl endUpdates];
}
There are two methods which are used to draw a cell if you know
1-viewForTableColumn
2-objectValueForTableColumn
In the above methods,when you draw your textfield you can give the dynamic height or your row as you are giving in heightforrowatindexpath method.By doing this your cell will get the accurate height. If you have any problem in calculating dynamic height then tell me I'll post the code here for calculating it.
I'm populating data into an array which is then being inserted into a UITableView. However once the screen gets filled, new cells won't show up because they get appended to the bottom. Is there a way to have it auto-scroll to the bottom upon adding an item? Also, the scrolling works but it isn't ideal. For example, to get to the last item, the user has to scroll and hold down that gesture to make the item appear. IE. My UITableView can hold up to 17 items in its view. After 17 the user can then scroll, however they would not be able to select item 18 because they would have to hold down their scroll gesture. In order to select item 18 they'd have to add say another 10 items.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
// Return the number of rows in the section.
// Usually the number of items in your array (the one that holds your list)
return [_items count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//Where we configure the cell in each row
static NSString *CellIdentifier = #"trap";
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell... setting the text of our cell's label
cell.textLabel.text = [_items objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"test");
}
If you have to hold your drag gesture to show 18rd item, I think the problem is your tableView's height didn't set properly. Try to set height to your visible frame height.
When the tableView was loaded,you can set contentOffset manually because you can get the tableViewContentSize this time.
You can not show the last item of the table.
The problem most likely is that your tableview’s height is bigger than
you screen size. Or it can be auto layout issue. Try to make your tableview's height smaller.
Is there a way to have it auto-scroll to the bottom upon adding an item?
[self.items addObject:[NSString stringWithFormat:#"Trawl %d", count]];
[self.tableView reloadData];
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:self.item.count - 1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES]
The following is my whole test Controller
#interface DPCalendarTestCreateEventViewController ()<UITableViewDelegate, UITableViewDataSource, DPCalendarTestOptionsCellDelegate>
#property (nonatomic, strong) UITableView *tableView;
#property (nonatomic, strong) NSMutableArray *items;
#end
#implementation DPCalendarTestCreateEventViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.items = #[#"TEST", #"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST",#"TEST"].mutableCopy;
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(doneButtonSelected)];
self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
self.tableView.dataSource = self;
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self.view addSubview:self.tableView];
}
- (void) doneButtonSelected{
[self.items addObject:[NSString stringWithFormat:#"Trawl %d", self.items.count]];
[self.tableView reloadData];
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:self.items.count - 1 inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [_items count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//Where we configure the cell in each row
static NSString *CellIdentifier = #"trap";
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell... setting the text of our cell's label
cell.textLabel.text = [_items objectAtIndex:indexPath.row];
return cell;
}
#end
i m trying to read some RSS data. I have the data that is of different sizes. the data is present in tabke view data object. I used the label to add the data and resize the dat. No success. Please help.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
NSLog(#"in the tabel view cell");
heightOfCell=[self tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Default"];
if (cell == nil)
{
//cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,heightOfCell) reuseIdentifier:#"Default"] autorelease];
UILabel *label = [[UILabel alloc] init];
NSString *cellText = [[TableViewData news] valueForKey:[NSString stringWithFormat:#"%d",[indexPath row]]];
UIFont *cellFont = [UIFont fontWithName:#"Helvetica" size:10.0];
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
label.text = [[TableViewData news] valueForKey:[NSString stringWithFormat:#"%d",[indexPath row]]];
CGSize labelSize = [[[TableViewData news] valueForKey:[NSString stringWithFormat:#"%d",[indexPath row]]] sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
label.lineBreakMode=UILineBreakModeWordWrap;
[label sizeThatFits:labelSize];
cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,heightOfCell) reuseIdentifier:#"Default"] autorelease];
//[label sizeToFit];
[cell addSubview:label];
[label release];
}
}
you need to use the following method.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 45;
}
you need to change the height as per your requirements
It should be noted that the default height is 44.
You need to implement the following method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// some code that compute row's height
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
// This is just Programatic method you can also do that by xib !
}
You can also change it in Interface Builder. Open the *.xib file, select the table, show the Size Inspector, and change the row height. But, please note that the default height is 44 pixels.
There are two methods to set the UITableViewCell's height .:
UITableView has a property named rowHeight, with which you can use to set all the UITableViewCell to the same row height;
If you implement the UITableViewDelegate protocol , and include tableView:heightForRowAtIndexPath: method, it's you responsbility to decide the current UITableViewCell'height. In practice, we always use the delegate method to set the cell's height, only if each cell's height may be dynamic! And the method is preference to the UITableView's rowHeight property!
So, I think you may prefer the second method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *cellText = [[TableViewData news] valueForKey:[NSString stringWithFormat:#"%d",[indexPath row]]];
UIFont *cellFont = [UIFont fontWithName:#"Helvetica" size:10.0];
CGSize labelSize = [cellText sizeWithFont:cellFont
constrainedToSize:constraintSize
lineBreakMode:UILineBreakModeWordWrap];
return lableSize ;
}
I saw a lot of solutions but all was wrong or uncomplet. You no need calculate nothing (no font, no size, nothing)...
You can solve all problems with 5 lines in viewDidLoad and autolayout.
This for objetive C:
_tableView.delegate = self;
_tableView.dataSource = self;
self.tableView.estimatedRowHeight = 80;//the estimatedRowHeight but if is more this autoincremented with autolayout
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0) ;
For swift 2.0:
self.tableView.estimatedRowHeight = 80
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.setNeedsLayout()
self.tableView.layoutIfNeeded()
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0)
Now create your cell with xib or into tableview in your Storyboard
With this you no need implement nothing more or override. (Don forget number os lines 0) and the bottom label (constrain) downgrade "Content Hugging Priority -- Vertical to 250"
You can donwload the code in the next url:
https://github.com/jposes22/exampleTableCellCustomHeight
References: http://candycode.io/automatically-resizing-uitableviewcells-with-dynamic-text-height-using-auto-layout/
You have to know the heights of all cells before the tableView:cellForRowAtIndexPath: delegate call which may require you to store heights inside your view controller or some other list.
The function to customise the heights of cells is tableView:heightForRowAtIndexPath:. The default height for a table view is 44 pixels, for reference.
You can find the documentation here.