How can I create a variable sized UITableViewCell? - iphone

I can't seem to get the text to actually span multiple lines. The heights look correct. What am I missing?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"StatusCell"] autorelease];
CGRect frame = cell.contentView.bounds;
UILabel *myLabel = [[UILabel alloc] initWithFrame:frame];
myLabel.text = [[person.updates objectAtIndex:indexPath.row] valueForKey:#"text"];
[cell.contentView addSubview:myLabel];
[myLabel release];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *text = [[person.updates objectAtIndex:indexPath.row] valueForKey:#"text"];
UIFont *font = [UIFont systemFontOfSize:[UIFont systemFontSize]];
CGSize withinSize = CGSizeMake(tableView.frame.size.width, 1000);
CGSize size = [text sizeWithFont:font constrainedToSize:withinSize lineBreakMode:UILineBreakModeWordWrap];
return size.height + 20;
}
Also, what am I missing that makes the labels appear longer than the table cell?

Tweetero provides an example of this in MessageListController.m. The code there renders the following screen:
(Pic is taken from Mashable).
The basic implementation outline:
When constructing a UITableViewCell, create and add a UILabel as a subview in the manner shown in tableviewCellWithReuseIdentifier:. Look for the creation of TEXT_TAG label.
when enriching the UITableViewCell with views, ensure that you format label properly, as is done in configureCell:forIndexPath, similarly look for the label tag TEXT_TAG.
Return the appropriate height for each cell, as is done in tableView:heightForRowAtIndexPath.

myLabel.numberOfLines = 2;
Check the docs for full info on how to use this property.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return theSizeYouWantYourCellToBe;
}

Related

How to fix the height of tableviewcell based on webview height? (i am loading webview in each tableviewcell)

// I am loading **HTML file** in **UIWebview** which is located on **tableviewcell**.
I want to fix height for cell based on HTML file height.
Note: loading HTML file will be different for every cell.(height is not constant for every HTML file)
To get the height of UIWebView object, first you need to load them. Then inside the delegate method of UIWebView you can get the height as per the html content like given below.
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSLog(#"%f",myWebView.scrollView.contentSize.height);
}
you can also get the height of UIWebView by JS insertion like this
[myWebView stringByEvaluatingJavaScriptFromString:#"document.body.offsetHeight;"];
In webViewDidFinishLoad method you have to store height based on webview object tag.
After that load your table and in below method give height accordingly.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
If I understood correctly..
Here you sets cell.textLabel.lineBreakMode and number of lines, for cell.textLabel. (0 - infinity)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
}
cell.textLabel.text = [news objectAtIndex:indexPath.row];
return cell;
}
Here you need to count the height of cell.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellText = [news objectAtIndex:indexPath.row];
UIFont *cellFont = [UIFont fontWithName:#"Helvetica-Bold" size:20.0f];
CGSize constraintSize = CGSizeMake(320.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont
constrainedToSize:constraintSize
lineBreakMode:UILineBreakModeWordWrap];
return labelSize.height + 20.0f;
}
Implement the UITableViewDelegate method - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *text = [self getItemForKey:kSummary];
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
//You will need to define kDefaultCellFont
CGSize labelSize = [text sizeWithFont:kDefaultCellFont
constrainedToSize:constraintSize
lineBreakMode:UILineBreakModeWordWrap];
return labelSize.height + ANY_OTHER_HEIGHT;
}
If you want more check the Link

Variable Height of TextView In TableView Cell

I have a basic UITableView, that I fill with a web service online, but I can't find a way to set the height of my cells (dynamic numbers of cells) according to the height of my textView.
Here's how I fill my cell :
UITextView *textView = (UITextView *)[cell viewWithTag:106];
textView.text = [[stories objectAtIndex:indexPath.row] objectForKey:#"texte"];
in my cellForRow methods :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
I tried this but get an error of EXC_BAD_ACCESS
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"PerleCell"];
UITextView *textView = (UITextView *)[cell viewWithTag:106];
textView.text = [[stories objectAtIndex:indexPath.row] objectForKey:#"texte"];
CGFloat *heightCell = (CGFloat*)textView.text.length;
return *heightCell;
}
In following method you can change height of your cell according to your textView.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
// Here check length of your textView
// and after getting length return that length;
NSString *myString = [[stories objectAtIndex:indexPath.row] objectForKey:#"texte"];
CGSize maximumSize = CGSizeMake(300, 9999);
UIFont *myFont = [UIFont fontWithName:#"Helvetica" size:14];
CGSize myStringSize = [myString sizeWithFont:myFont constrainedToSize:maximumSize lineBreakMode:UILineBreakModeWordWrap];
return size.height;
}
Also in cellForRowAtIndexPath method calculate width of string in same manner and then give frame of width of yourtextView accordingly. After that add your textview on cell's contentView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
// Create cell here by using any style and for this you can google some what that how to create cell in UITableView
// Here check length of your textView
// and after getting length return that length;
NSString *myString = [[stories objectAtIndex:indexPath.row] objectForKey:#"texte"];
CGSize maximumSize = CGSizeMake(300, 9999);
UIFont *myFont = [UIFont fontWithName:#"Helvetica" size:14];
CGSize myStringSize = [myString sizeWithFont:myFont constrainedToSize:maximumSize lineBreakMode:UILineBreakModeWordWrap];
UITextView *textView = [[UITextView alloc]initWithFrame:CGRectMake(0,0,300,size.height)];
textView.text = myString;
[cell.contentView addSubView:textView];
return cell;
}

increasing the height of cell loading from a custom class? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to adjust the hieght of the cell table when loading from the custom cells?
I have an application in which I am loading the cell from different custom class object.It was working fine.But my problem is I am adding a text view on this subclass. I need to adjust the height of the cell in the table view according to the contents of that text view.`
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
return 125;
}
else
{
return 245;
}
}
Now I am doing like this. But I want the cell height to be changed according to the text view content size in the custom class cell. Can anybody help me?
You can do it in easy way just look at this :
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
UILabel *label = nil;
cell = [tv dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:#"Cell"] autorelease];
label = [[UILabel alloc] initWithFrame:CGRectZero];
[label setLineBreakMode:UILineBreakModeWordWrap];
[label setMinimumFontSize:FONT_SIZE];
[label setNumberOfLines:0];
[label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
[label setTag:1];
[[cell contentView] addSubview:label];
}
}
then u can Calculate the Cell Height and here an full example link
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
NSString *text = [items objectAtIndex:[indexPath row]];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_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_CONTENT_MARGIN * 2);
}

struggling with formatting dynamic row height in UITableView

I am trying to resize the height of my row in UITableView based on the text length. I have the following code:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellText =[[topics objectAtIndex:indexPath.row] name];
UIFont *cellFont = [UIFont fontWithName:#"ArialMT" size:17.0];
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
return labelSize.height + 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont fontWithName:#"ArialMT" size:17.0];
}
}
However, it messes up with the UIImageView and the UIDetailText, image shown below:
How do I fix this?
I've tried:
[cell.imageView setContentMode:UIViewContentModeScaleToFill];
[cell.imageView setFrame:CGRectMake(0, 0, 16,16)];
[cell.imageView setBounds:CGRectMake(0, 0, 16,16)];
[cell.imageView setAutoresizingMask:UIViewAutoresizingNone];
[cell.imageView setAutoresizesSubviews:NO];
and none seems to work
The work of changing cell's subviews' frames is done in - (void)layoutSubviews of UITableViewCell class, so if you want alter that behavior you can subclass common UITableViewCell and then do smth like:
#implementation MyTableViewCell
- (void)layoutSubviews {
[super layoutSubviews];
self.imageView.frame = CGRectMake( -- your own size -- );
}
#end
Instead of subclassing as suggested by others, you could also add your own subviews to the cell’s content view.
From Customizing Cells:
If you want the cell to have different
content components and to have these
laid out in different locations, or if
you want different behavioral
characteristics for the cell, you have
two alternatives. You can add subviews
to the contentView property of the
cell object or you can create a custom
subclass of UITableViewCell.
You should add subviews to a cell’s content view when your content layout can be specified entirely with the appropriate autoresizing settings and when you don’t need to modify the default behavior of the cell.
You should create a custom subclass when your content requires custom layout code or when you need to change the default behavior of the cell, such as in response to editing mode.
See this example:
#define CUSTOM_IMAGE_TAG 99
#define MAIN_LABEL 98
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UIImageView *customImageView = nil;
UILabel *mainLabel = nil;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
customImageView = [[[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 40.0f, 40.0f)] autorelease];
customImageView.tag = CUSTOM_IMAGE_TAG;
[cell.contentView addSubview:customImageView];
mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(60.0f, 10.0f, 100.0f, 21.0f)] autorelease];
mainLabel.tag = MAIN_LABEL;
mainLabel.numberOfLines = 0;
[cell.contentView addSubview:mainLabel];
} else {
customImageView = (UIImageView *)[cell.contentView viewWithTag:CUSTOM_IMAGE_TAG];
mainLabel = (UILabel *)[cell.contentView viewWithTag:MAIN_LABEL];
}
// Configure the cell.
CGRect frame = mainLabel.frame;
frame.size.height = ... // dynamic height
mainLabel.frame = frame;
return cell;
}
Obviously, you still need to implement tableView:heightForRowAtIndexPath:.
I think the built in imageView will ignore your attempts to resize it. Subclass UITableViewCell and add your own custom UIImageView to it. Then you can control all aspects of your image view.
-- wisenomad's solution will work without having to add your own custom image view and labels. --
You will also have to change the frame of the textLabel. Here is an example.
- (void)layoutSubviews {
[super layoutSubviews];
float sideLength = self.frame.size.height;
self.imageView.frame = CGRectMake(0.0, 0.0, sideLength, sideLength);
CGRect textLabelFrame = self.textLabel.frame;
self.textLabel.frame = CGRectMake(44.0, textLabelFrame.origin.y, textLabelFrame.size.width - 44.0 + textLabelFrame.origin.x, textLabelFrame.size.height);
}

Wrap words in uitableview, iphone [duplicate]

This is on iPhone 0S 2.0. Answers for 2.1 are fine too, though I am unaware of any differences regarding tables.
It feels like it should be possible to get text to wrap without creating a custom cell, since a UITableViewCell contains a UILabel by default. I know I can make it work if I create a custom cell, but that's not what I'm trying to achieve - I want to understand why my current approach doesn't work.
I've figured out that the label is created on demand (since the cell supports text and image access, so it doesn't create the data view until necessary), so if I do something like this:
cell.text = #""; // create the label
UILabel* label = (UILabel*)[[cell.contentView subviews] objectAtIndex:0];
then I get a valid label, but setting numberOfLines on that (and lineBreakMode) doesn't work - I still get single line text. There is plenty of height in the UILabel for the text to display - I'm just returning a large value for the height in heightForRowAtIndexPath.
Here is a simpler way, and it works for me:
Inside your cellForRowAtIndexPath: function. The first time you create your cell:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:17.0];
}
You'll notice that I set the number of lines for the label to 0. This lets it use as many lines as it needs.
The next part is to specify how large your UITableViewCell will be, so do that in your heightForRowAtIndexPath function:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellText = #"Go get some text for your cell.";
UIFont *cellFont = [UIFont fontWithName:#"Helvetica" size:17.0];
CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
return labelSize.height + 20;
}
I added 20 to my returned cell height because I like a little buffer around my text.
Updated Tim Rupe's answer for iOS7:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:17.0];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellText = #"Go get some text for your cell.";
UIFont *cellFont = [UIFont fontWithName:#"Helvetica" size:17.0];
NSAttributedString *attributedText =
[[NSAttributedString alloc]
initWithString:cellText
attributes:#
{
NSFontAttributeName: cellFont
}];
CGRect rect = [attributedText boundingRectWithSize:CGSizeMake(tableView.bounds.size.width, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
return rect.size.height + 20;
}
A brief comment / answer to record my experience when I had the same problem. Despite using the code examples, the table view cell height was adjusting, but the label inside the cell was still not adjusting correctly - solution was that I was loading my cell from a custom NIB file, which happens after the cell height in adjusted.
And I had my settings inside the NIB file to not wrap text, and only have 1 line for the label; the NIB file settings were overriding the settings I adjusted inside the code.
The lesson I took was to make sure to always bear in mind what the state of the objects are at each point in time - they might not have been created yet! ... hth someone down the line.
If we are to add only text in UITableView cell, we need only two delegates to work with (no need to add extra UILabels)
1) cellForRowAtIndexPath
2) heightForRowAtIndexPath
This solution worked for me:-
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:16];
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
cell.textLabel.text = [mutArr objectAtIndex:indexPath.section];
NSLog(#"%#",cell.textLabel.text);
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"arrow.png" ]];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGSize labelSize = CGSizeMake(200.0, 20.0);
NSString *strTemp = [mutArr objectAtIndex:indexPath.section];
if ([strTemp length] > 0)
labelSize = [strTemp sizeWithFont: [UIFont boldSystemFontOfSize: 14.0] constrainedToSize: CGSizeMake(labelSize.width, 1000) lineBreakMode: UILineBreakModeWordWrap];
return (labelSize.height + 10);
}
Here the string mutArr is a mutable array from which i am getting my data.
EDIT :- Here is the array which I took.
mutArr= [[NSMutableArray alloc] init];
[mutArr addObject:#"HEMAN"];
[mutArr addObject:#"SUPERMAN"];
[mutArr addObject:#"Is SUPERMAN powerful than HEMAN"];
[mutArr addObject:#"Well, if HEMAN is weaker than SUPERMAN, both are friends and we will never get to know who is more powerful than whom because they will never have a fight among them"];
[mutArr addObject:#"Where are BATMAN and SPIDERMAN"];
Now the tableviews can have self-sizing cells. Set the table view up as follows
tableView.estimatedRowHeight = 85.0 //use an appropriate estimate
tableView.rowHeight = UITableViewAutomaticDimension
Apple Reference
I use the following solutions.
The data is provided separately in a member:
-(NSString *)getHeaderData:(int)theSection {
...
return rowText;
}
The handling can be easily done in cellForRowAtIndexPath.
Define the cell / define the font and assign these values to the result "cell".
Note that the numberoflines is set to "0", which means take what is needed.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIFont *cellFont = [UIFont fontWithName:#"Verdana" size:12.0];
cell.textLabel.text= [self getRowData:indexPath.section];
cell.textLabel.font = cellFont;
cell.textLabel.numberOfLines=0;
return cell;
}
In heightForRowAtIndexPath, I calculate the heights of the wrapped text.
The boding size shall be related to the width of your cell. For iPad this shall be 1024.
For iPhone en iPod 320.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIFont *cellFont = [UIFont fontWithName:#"Verdana" size:12.0];
CGSize boundingSize = CGSizeMake(1024, CGFLOAT_MAX);
CGSize requiredSize = [[self getRowData:indexPath.section] sizeWithFont:cellFont constrainedToSize:boundingSize lineBreakMode:UILineBreakModeWordWrap];
return requiredSize.height;
}
I found this to be quite simple and straightForward :
[self.tableView setRowHeight:whatEvereight.0f];
for e.g. :
[self.tableView setRowHeight:80.0f];
This may or may not be the best / standard approach to do so, but it worked in my case.
Try my code in swift . This code will work for normal UILabels also.
extension UILabel {
func lblFunction() {
//You can pass here all UILabel properties like Font, colour etc....
numberOfLines = 0
lineBreakMode = .byWordWrapping//If you want word wraping
lineBreakMode = .byCharWrapping//If you want character wraping
}
}
Now call simply like this
cell.textLabel.lblFunction()//Replace your label name
I think this is a better and shorter solution. Just format the UILabel (textLabel) of the cell to auto calculate for the height by specifying sizeToFit and everything should be fine.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
cell.textLabel.text = #"Whatever text you want to put here is ok";
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
[cell.textLabel sizeToFit];
return cell;
}
I don't think you can manipulate a base UITableViewCell's private UILabel to do this. You could add a new UILabel to the cell yourself and use numberOfLines with sizeToFit to size it appropriately. Something like:
UILabel* label = [[UILabel alloc] initWithFrame:cell.frame];
label.numberOfLines = <...an appriate number of lines...>
label.text = <...your text...>
[label sizeToFit];
[cell addSubview:label];
[label release];