Monday, November 23, 2009

Multi-line UITableViewCell using UILabel

No need for UITextViews or custom UITableViewCells. You can use standard UITableViewCellStyles and make the detailTextLabel accept multiple lines and specify its line break mode. The code would be:

static NSString *CellIdentifier = @"MyCell"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2
reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.text = @"Label';
cell.detailTextLabel.text = @"Multi-Line\nText";
cell.detailTextLabel.numberOfLines = 2;
cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
You will also need to return a suitable height for the multi-line cell. A height of (44.0 + (numberOfLines - 1) * 19.0) should work fine.

Update: As Vaibhav mentions in the comments, you can use variants of sizeWithFont from the NSString UIKit Additions to get the required height. I guess sizeWithFont:forWidth:lineBreakMode is the one to use here. Thanks for your input!


Anonymous said...

Thanks for solution - it works great.

One question: did you arrive at the + 19.0 when calculating the height of the cell by trial and error, or can it be found from properties?

Ahmed Abdelkader said...

Glad you liked it.

As far as I can remember, I measured the height of multiline address fields in the Contacts application when the number of lines was 1,2, 3 and 4. I used these heights to derive the function above. A linear model made sense and we know that the height of a single-line cell is 44.0 (think y-intercept), so we just need to find the increment/line (think slope). It worked okay for the range of lines I was interested in.

This is how I got the function. I believe the 19.0 is related to the default font, so you might take a look at that and adjust the function accordingly, in case you have a different font.

Good luck and let us know how that turns out for you!

Anonymous said...

My thanks as well. Sooo glad to find this one.

rohith said...

For developing Multiple View with Navigation Based application ,In my app I did moving from one view to another view (1->2 and 2->1),but I am unable to move from 2->3 ,3 ->4 and reverse too, can u pl solve, how can we move from 2(In 2nd view Some text will be present ) to 3rd view(again some more text will be displayed .And moving from one view to another view with text content how can we switch ?Using buttons / (any other easy way to solve this ) at the end of the text field

Kindly , please provide a tutor/code /suggestion for Multiple Views using Navigation Based Application.

What I mean is suppose if we take 4 Views.(Moving from 1 to 2 to 3 to 4 and VICE VERSA ,using PREVIOUS and FORWARD BUTTON within these views ).
In 1st View,data will be row
and when we click any ROW CONTENT, it must go to 2nd view(which contain some TEXTS, with 2 paragraph with some spacing between 2 paragraphs) .

And in the same way we click on 2nd View it must go to 3rd view ( when we click ,here also TEXT will be displayed and should have a button like BACK(2 nd View) and FORWARD (4 View)BUTTON ).

Generally ,It would be better if we display TEXT in LANDSCAPE MODE .

I will be very thankful if u provide a tutor on it......


Ahmed Abdelkader said...

To move to a new view you can use either [self.navigationController pushViewController:nextViewController animated:YES] or [self.viewController presentModalViewController]. To move back, you use the corresponding method: popViewController or dismissModalViewController respectively.

Anonymous said...

Thanks for this. It worked great!

Anonymous said...

Nice, thanks!

Vaibhav said...

To calculate height dynamically please see methods available with NSString Class.

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size

- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode

- (CGSize)sizeWithFont:(UIFont *)font minFontSize:(CGFloat)minFontSize actualFontSize:(CGFloat *)actualFontSize forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode

Ahmed Abdelkader said...

Thanks a lot Vaibhav!

Anonymous said...

Works great. If you've been able to get this to work with cell.imageView.image (i.e. a UIImage), please let us know how you did it, as I can't get this to work when displaying images in the UITableViewCell.

Kadari said...

Thank U Buddy..!!

Anonymous said...

Does sizeWithFont still work given that there's another text label before the detail text?

Ahmed Abdelkader said...

sizeWithFont operates on a given string independently of your layout. You'll still need to pass the font used by the label in question to get meaningful results.

Napolux said...

Thanks, this made my day!

sanjay changani said...

Very Useful