Jesper Martensson
Jesper Martensson

Reputation: 1248

How to scale UITableViewCell's after the amount of content(text) in them?

How do I achieve this? Can't find any useful information on the matter.... I have a forum in my app, and depending on how big the posts are, the cell's should scale after the amount of text... Is it possible to set this in storyboard or are you forced to program it? /Regards

EDIT Here below is my code in the tableView. The cell's has 3 labels, 2 are more or less static (always same amount of text) and the 3rd is dynamic (commentLabel) which can contain everything between 1 row up till 70 rows, for example. Now I want the cell's to expand after commentLabel's height...

#import "ForumthreadViewController.h"

@interface ForumthreadViewController ()

@end

@implementation ForumthreadViewController

@synthesize tableView;
@synthesize textField;

@synthesize refreshButton;

@synthesize forumThreadDataProvider;

@synthesize dateFormatter;

@synthesize items;
@synthesize taskId;
@synthesize forumThreadId;

- (void)viewDidLoad
{
[super viewDidLoad];

self.forumThreadDataProvider = [[MLForumThreadDataProvider alloc] initWithDelegate:self];

self.navigationItem.rightBarButtonItems = [NSArray arrayWithObjects:self.refreshButton, [self initLoadingIndicator], nil];

NSLocale *locale = [NSLocale currentLocale];
self.dateFormatter = [[NSDateFormatter alloc] init]; 
NSString *dateFormat = [NSDateFormatter dateFormatFromTemplate:@"E MMM d" options:0 locale:locale];
[self.dateFormatter setDateFormat:dateFormat];
[self.dateFormatter setLocale:locale];

[self refreshData];
}

- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

 - (BOOL)hidesBottomBarWhenPushed
{
return TRUE;
}

- (void)setLoadingState : (BOOL)loading
{
[super setLoadingState:loading];
if (loading)
{
    [self.refreshButton setEnabled:NO];
}
else
{
    [self.refreshButton setEnabled:YES];
}
}

 #pragma mark - Text field

- (void)textFieldDidBeginEditing:(UITextField *)pTextField
{
[self animateTextField: pTextField up: YES];
}

- (void)textFieldDidEndEditing:(UITextField *)pTextField
{
[self animateTextField: pTextField up: NO];
[pTextField resignFirstResponder];
}

- (void) animateTextField: (UITextField*) pTextField up: (BOOL) up
{
const int movementDistance = 215; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed

int movement = (up ? -movementDistance : movementDistance);

[UIView beginAnimations: @"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}

- (BOOL)textFieldShouldReturn:(UITextField *)pTextField
{
[self setLoadingState:YES];
[pTextField resignFirstResponder];

NSUserDefaults *userStorage = [NSUserDefaults standardUserDefaults];

NSString *alias = [self urlEncode:[userStorage objectForKey:@"alias"]];
NSString *email = [self urlEncode:[userStorage objectForKey:@"email"]];
NSString *who = [self getUniqueDeviceId];
NSString *comment = [self urlEncode:[pTextField text]];

comment = [comment stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
who = [who stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

if([self isBlank:comment])
{
    [self setLoadingState:NO];
    pTextField.text = @"";
    return NO;
}
if([self isBlank:alias])
{
    [self showMessagePopup:NSLocalizedString(@"MessageMustChooseAlias", nil)];
    return NO;
}

[self.forumThreadDataProvider startSendPost:self.taskId : self.forumThreadId : alias : who : email : comment];

pTextField.text = @"";

return YES;
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.items count];
}

- (UITableViewCell *)tableView:(UITableView *)pTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"ForumthreadCell";
UITableViewCell *cell = [pTableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

        }

Feedback *item = [self.items objectAtIndex:indexPath.row];

UILabel *aliasLabel = (UILabel *)[cell viewWithTag:1];
UILabel *commentLabel = (UILabel *)[cell viewWithTag:2];
UILabel *dateLabel = (UILabel *)[cell viewWithTag:3];



[aliasLabel setText:item.alias];
[commentLabel setText:item.comment];
[dateLabel setText:[self.dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:(double)item.time]]];

commentLabel.numberOfLines = 0;
// commentLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
//commentLabel.lineBreakMode = UILineBreakModeWordWrap;
[commentLabel sizeToFit];

// CGSize constraint = CGSizeMake(300, 2000);
// CGSize size = [item.comment sizeWithFont:[UIFont boldSystemFontOfSize:11] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
//[commentLabel setFrame:CGRectMake(16, 30, 300, size.height)];

return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];

if (cell) {        
    UILabel *commentLabel = (UILabel *)[cell viewWithTag:2];
    return commentLabel.frame.size.height;
}  
else
   return 30;
}



#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

}

#pragma mark - Fetch data

- (IBAction) refreshData
{
[self setLoadingState:YES];
[self.forumThreadDataProvider startFetchResult:self.taskId : self.forumThreadId];

//[self fetchForumPosts:self.taskId : self.feedbackId];
}

 - (void) onFetchResultDone : (NSArray *) result
{
self.items = result;
[self.tableView reloadData];
[self setLoadingState:NO];
}

- (void) onCreatePostDone : (Result *) result
{
if ([result success])
{
    [self refreshData];
}
else
{
    [self showMessagePopup:[NSString stringWithFormat:NSLocalizedString(@"MessageErrorCreateForumPost", nil), result.code]];
}
[self setLoadingState:NO];
}

 - (void) onForumRequestFail : (NSError *) result
{
[self showNoConnectionPopup];
[self setLoadingState:NO];
}

Picture of the error: http://tinypic.com/view.php?pic=1jssyc&s=6

Upvotes: 1

Views: 838

Answers (1)

WDUK
WDUK

Reputation: 19030

You're going to have to do this programmatically I'm afraid.

To do so, you need to implement tableView:heightForRowAtIndexPath: in your UITableView delegate. This will provide you with the table view instance, as well as the index path for the row concerned.

Update: In order to do so, you'll need to keep a track of the height of the cell based on it's index path when creating it. You can implement it as so:

@interface ForumthreadViewController() {
    NSMutableDictionary* m_cellHeights;
}
@end

// Init your dictionary in your init method using m_cellHeights = [NSMutableDictionary alloc] init];

- (UITableViewCell *)tableView:(UITableView *)pTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ...
    [commentLabel setText:item.comment];
    [dateLabel setText:[self.dateFormatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:(double)item.time]]];

    commentLabel.numberOfLines = 0;
    // commentLabel = [[[UILabel alloc] initWithFrame:CGRectZero] autorelease];
    //commentLabel.lineBreakMode = UILineBreakModeWordWrap;
    [commentLabel sizeToFit];

    [m_cellHeights setObject:@(commentLabel.frame.size.height) forKey:indexPath];
    ...
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSNumber* value = [m_cellHeights objectForKey:indexPath];

    if (value) {
        return [value floatValue];
    }

    return 0.0;
}

Edit: From looking at your code you've provided, where are the UILabel being created?

UILabel *aliasLabel = (UILabel *)[cell viewWithTag:1];
UILabel *commentLabel = (UILabel *)[cell viewWithTag:2];
UILabel *dateLabel = (UILabel *)[cell viewWithTag:3];

This code is trying to extract UILabels from the cell, but nowhere in the cell generation code are these labels being created. You will need to create and add them as so (I've used ... to prevent excessive code being reprinted from your question:

    - (UITableViewCell *)tableView:(UITableView *)pTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    ...

    if (cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

        UILabel* newAlias = [[UILabel alloc] initWithFrame:...]; // Provide the frame you need
        newAlias.tag = 1;
        [cell.contentView newAlias];

        // Do the same for date and comment
    }

    Feedback *item = [self.items objectAtIndex:indexPath.row];

    UILabel *aliasLabel = (UILabel *)[cell.contentView viewWithTag:1];
    UILabel *commentLabel = (UILabel *)[cell.contentView viewWithTag:2];
    UILabel *dateLabel = (UILabel *)[cell.contentView viewWithTag:3];

    ...

    return cell;
}

Upvotes: 1

Related Questions