guys.
I have UITableView with different cells and I have code, which counts height. In one project it works perfect, but in second it returns height equals 0.
What could be causing this?
My code:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
CGFloat cellWidth = 320.0f;
CGSize size = [cell.textLabel.text sizeWithFont:cell.textLabel.font constrainedToSize:CGSizeMake(cellWidth, CGFLOAT_MAX) lineBreakMode:cell.textLabel.lineBreakMode];
CGFloat height = size.height;
NSLog(#"Height: %f", height);
return height;
}
The heightForRowAtIndexPath: delegate method gets called before the cellForRowAtIndexPath: delegate method. In your code you are calculating your cell height based on cell.textLabel.text, but the text in the cell has not been set yet.
You need to get the text to use in this method from somewhere else other than the table cell (presumably you can get it from wherever you are getting it from when you set the textlabel.text value in cellForRowAtIndexPath).
Related
I'm using a grouped uitableview. I have a lot of sections.
In the first section there is just one UITableViewCell. In this cell, I will show a text.
The problem is that I don't know the number of characters of the text and I would like to change the height of cell to show entire text.
can someone help me?
Thanks
in the UItableViewDelegate method - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath you can return height for specific row. For that you must know the length of the string you want to display in that row.
see this link Get tableView:heightForRowAtIndexPath: to happen after tableView:cellForRowAtIndexPath:?
You will have to use heightForRowAtIndexPath. Within that you will have to do all the calculations that you do in the cell's layoutsubviews or in cellForRowAtIndexPath too. For doing so you will have to figure out how long the text is. You will have to access the text in cellForRowAtIindexPath anyway. So why don't you know how long the text will be?
To determine the size of the actual text you can use NSSTring's sizeWithFont:forWidth:lineBreakMode:.
I have solved the problem applying the code below and creating a property numberOfTextRows.
(CGFloat)tableView:(UITableView *)t heightForRowAtIndexPath:(NSIndexPath *)indexPath
float height = 45.0f;
if (indexPath.section == 0 && indexPath.row == 0) {
CGSize theSize = [self.strResult sizeWithFont:[UIFont systemFontOfSize:12.0f] constrainedToSize:CGSizeMake(265.0f, 9999.0f) lineBreakMode:UILineBreakModeWordWrap];
self.numberOfTextRows = round(theSize.height / 12);
if ((indexPath.section == height) || (self.numberOfTextRows < 2)) {
height = 45;
} else {
height = theSize.height + 16;
}
}
return height;
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = self.numberOfTextRows;
I create custom cells within my tableview some have images and are tall some are just text. The height of the cells are calculated in heightForRowAtIndexPath, which I beleive is done before cellForRowAtIndexPath is called. I want to place an imageview at the bottom of the cell regardless of heigh, but I am not sure how to get the calculated height from within cellForRowAtIndexPath?
Too late for an answer..
But, like #user216661 pointed out, the problem with taking the height of the Cell or the ContentView is that it returns the cells original height. Incase of rows with Variable height, this is an issue.
A better solution is to get the Rect of the Cell (rectForRowAtIndexPath) and then get the Height from it.
- (UITableViewCell *)tableView:(UITableView *)iTableView cellForRowAtIndexPath:(NSIndexPath *)iIndexPath {
UITableViewCell *aCell = (UITableViewCell *)[iTableView dequeueReusableCellWithIdentifier:aCellIdentifier];
if (aCell == nil) {
CGFloat aHeight = [iTableView rectForRowAtIndexPath:iIndexPath].size.height;
// Use Height as per your requirement.
}
return aCell;
}
You can ask the delegate, but you'll be asking twice since the tableView already asks and sizes the cell accordingly. It's better to find out from the cell itself...
// in cellForRowAtIndexPath:, deque or create UITableViewCell *cell
// this makes the call to heightForRow... and sizes the cell
CGFloat cellHeight = cell.contentView.bounds.size.height;
// alter the imageView y position (assuming the rest of the frame is correct)
CGRect imageFrame = myImageView.frame;
imageFrame.y = cellHeight - imageFrame.size.height; // place the bottom edge against the cell bottom
myImageView.frame = imageFrame;
You are allowed to call heightForRowAtIndexPath yourself! Just pass the indexPath from cellForRowAtIndexPath as an argument and you can know the height of the cell you are setting up.
Assuming you are using a UITableViewController, just use this inside cellForRowAtIndexPath...
float height = [self heightForRowAtIndexPath:indexPath]
I am trying to create a table with cells that contain UITextViews inside them for variable amounts of text. I need to specify the height of each cell to match the content size of the textviews. I am using...
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITextView *historyNode = [[[UITextView alloc]init]autorelease];
historyNode.text = (#"%#",[globalArrayWithStrings objectAtIndex:[indexPath row]]);
NSLog(#"%2.0f",historyNode.frame.size.height);
return historyNode.contentSize.height;
}
For some reason, it always prints 0. If i print the height of a textview created in interface builder, it prints the correct value. Any ideas how to get around this or why I can't get the size of a textview until it is added to the view.
You can use the sizeWithFont: method to find the dynamic height. Your heightForRowAtIndexPath: should look like this.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *text = [globalArrayWithStrings objectAtIndex:[indexPath row]];
CGSize maxSize = CGSizeMake(textViewWidth, 999); // 999 can be any maxmimum height you want
CGSize newSize = [text sizeWithFont:aFont constrainedToSize:maxSize lineBreakMode:textViewLineBreakMode];
return newSize.height;
}
First set the frame of the uitextView and then you will get the height of the text view.
im making a iphone app so that any text in the detailTextlabel will fit no matter what
for example...if the detailTextLabel is short it will show a normal size cell however it if is long it will show a bigger cell
thank you :D
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
CGSize maxSize = CGSizeMake(max_size);
CGSize cellSize = [yourString
sizeWithFont:[UIFont systemFontOfSize:15]
constrainedToSize:maxSize
lineBreakMode:UILineBreakModeWordWrap];
return cellSize.height;
}
Consider my implementation:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (theSection) {
case 0:
if (indexPath.row ==6) //the row you need to check for height (if any)
{
if([yourString length]<=35) // if less than 35 chars, just return a basic size of 50
{
return 50;
}
CGSize detailSize = [yourString sizeWithFont:[UIFont systemFontOfSize:20]constrainedToSize:CGSizeMake(270, 4000)lineBreakMode:UILineBreakModeWordWrap];
return detailSize.height;
}
hope it helps, to help your understanding you may want to have a look at 'sizeWithFont' to understand what this is doing to return a size.
You have to use the tableView:heightForRowAtIndexPath: method on your UITableViewDelegate to return the height of the row. Note that this method should be very fast if you have more than a few rows, as it will be called for every row in the table rather than just the visible rows.
I am overloading the delegate method -tableView:heightForRowAtIndexPath: and using -sizeWithFont:constrainedToSize: to programmatically set the height of the cell, based on the text in that cell:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.section) {
case(kAboutViewOverviewSection): {
switch (indexPath.row) {
case(kAboutViewOverviewSectionRow): {
NSString *text = NSLocalizedString(#"kAboutViewOverviewSectionFieldText", #"");
CGSize s = [text sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(280, 500)];
return s.height + 13;
}
default: {
break;
}
}
break;
}
default: {
break;
}
}
return 44.0;
}
This works when the table is first drawn. However, when I change the orientation of the device, from portrait to landscape, the cell height does not change.
I tried overriding the -shouldAutorotateToInterfaceOrientation: method in my table view controller:
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
[self.tableView reloadData];
return YES;
}
This should reload the table data and (presumably) redraw the table cell views. But this does not have any effect.
Is there a way to force a cell to redraw with a new height, when the device is rotated?
EDIT: I have tried the following, to no effect:
- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
[self.tableView reloadData];
}
Here is what the application looks like in portrait orientation:
Here is what the application looks like in landscape orientation:
There is a gap between the top and bottom edges of the content.
EDIT 2:
Adjusting the size parameter via the table frame's width helped fix this display issue:
CGSize s = [text sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake([tableView frame].size.width,500)];
It's less than optimal, but the simplest solution is to call -reloadData on the table.
A better solution would be to call -beginUpdates, -deleteRowsAtIndexPaths:withRowAnimation:, -insertRowsAtIndexPaths:withRowAnimation:, and -endUpdates or simply -reloadSections:withRowAnimation: if targeting 3.0 only. This will add animation.
Edit: And you will also need a proper tableView:heightForRowAtIndexPath:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGSize textSize = [[self textForRowAtIndexPath:indexPath] sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake([tableView frame].size.width - 20, 500)];
return textSize.height + 13.0f;
}
(where textForRowAtIndexPath: is a method that returns the cell's text)