IOS Tableview custom cell with dynamic label height - ios

I have trying to figure out this for quite some time :
I have a custom cell in tableview which has two labels one below other. The top label can be of one line or two line max. The bottom label is restricted to just one line.
The top label will always be there but the bottom label will be there for some cells and my not be there for some other cells.
I need a way to figure out how to arrange these labels centered vertically. I tried making the top label dynamic by using cell.label1.numberOfLines = 0; But then the label1 is not really restricted to 2 lines.
I tried to center these labels vertically by computing the height of first label and then arranging both labels centered.
If I restrict the number of lines to 2 using xib, then the height for first label always computes as 2 lines, even if the label consumes 1 line. One issue always which I see is if I use [cell.label1 sizeToFit]; then while scrolling the table the label always seem to change the text shown . The text shown is always for the respective label but the text sometimes wraps midway sometimes uses the full line.
Here is my code for reference :
CustomCell1 *cell = (CustomCell1 *)[self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell1" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.label1.lineBreakMode = UILineBreakModeWordWrap;
cell.label1.numberOfLines = 0;
cell.label1.tag = [indexPath row];
}
cell.label1.text = [[responseArray objectAtIndex:[indexPath row]] text];
if([[[responseArray objectAtIndex:[indexPath row]] isDone] isEqualToString:#"N"]) {
cell.label2.text = #"";
} else {
cell.label2.text = #"Done";
}
//[cell.label1 sizeToFit];
CGSize label1Size = [cell.label1 frame].size;
CGFloat label1Height = label1Size.height;
CGRect label1Frame = cell.label1.frame;
int numLines = (int)(label1Height/cell.label1.font.leading);
CGSize label2Size = [cell.label2 frame].size;
CGFloat label2Height = label2Size.height;
CGRect label2Frame = cell.label2.frame;
if(numLines > 1) {
if([cell.label2.text isEqualToString:#""]) {
//if label2 == "" then center label1
label1Frame.origin.y = cellHeight/2 - label1Height/2;
cell.label1.frame = label1Frame;
} else {
label1Frame.origin.y = 12;
cell.label1.frame = label1Frame;
label2Frame.origin.y = 52;
cell.label2.frame = label2Frame;
}
} else {
if([cell.label2.text isEqualToString:#""]) {
CGRect frame = cell.label1.frame;
frame.origin.y = cellHeight/2 - label1Height/2;
cell.label1.frame = frame;
} else {
label1Frame.origin.y = cellHeight/2 - label1Height/2;
cell.label1.frame = label1Frame;
label2Frame.origin.y = cellHeight/2;
cell.label2.frame = label2Frame;
}
}
Please help me IOS gurus with your suggestions.

It would be better to move the resizing calculations to layoutSubviews.
//CustomCell.m
- (void)layoutSubviews{
CGRect label1Frame = self.label1.frame;
//Calculate the size of label 1
CGSize label1Size = [self.label1.text sizeWithFont:[self.label1 font]
constrainedToSize:CGSizeMake(label1Frame.size.width,42.0f)
lineBreakMode:NSLineBreakByTruncatingTail];
label1Frame.size.height = label1Size.height;
CGRect label2Frame = self.label2.frame;
//Calculate the size of label 2
CGSize label2Size = [self.label2.text sizeWithFont:[self.label2 font]
constrainedToSize:CGSizeMake(label2Frame.size.width,21.0f)
lineBreakMode:NSLineBreakByTruncatingTail];
label2Frame.size.height = label2Size.height;
//Total height of labels
CGFloat totalHeight = label1Frame.size.height+label2Frame.size.height+5.0f;
//For centering half of difference of two labels with cell
label1Frame.origin.y = (self.frame.size.height - totalHeight)/2.0f;
self.label1.frame = CGRectIntegral(label1Frame);
label2Frame.origin.y = label1Frame.origin.y+label1Frame.size.height+5.0f;
self.label2.frame = CGRectIntegral(label2Frame);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
CustomCell1 *cell = (CustomCell1 *)[self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell1" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.label1.lineBreakMode = UILineBreakModeWordWrap;
cell.label1.numberOfLines = 2;
cell.label1.tag = [indexPath row];
}
cell.label1.text = [[responseArray objectAtIndex:[indexPath row]] text];
if([[[responseArray objectAtIndex:[indexPath row]] isDone] isEqualToString:#"N"]) {
cell.label2.text = #"";
} else {
cell.label2.text = #"Done";
}
return cell;
}

Related

UITableView mess up after resizing | Objective-C

I'm using a TableView to create a chat app. Where each cell represent a msg. The cell height change based on the contents of the msg.
For example if its a photo it will have a fixed size.
If its a text it will have a size depend of number of line in msg.
Also the whole TableView change size when the user try to send a msg based on the size of the keyBoard appeared.
The problem is that when the tableView size changes, the tableView cells get messed up!
This only happen when is scroll down (re-render the cells that disappear)
Update: This happened also if some of the cells where invisible (big tableView). before the re-sizing. And also it does not have anything with the type. Because it does the same if the msgs are all text
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([[[msg objectAtIndex:indexPath.row] objectForKey:#"type"] isEqualToString:#"msg"]) {
int numberOfline= [[[msg objectAtIndex:indexPath.row] objectForKey:#"line"] intValue];
return topMergeH + topBubbleH + bottomBubbleH + bottomMergeH + (bubbleHieght*numberOfline);
}
else
return topMergeH + topBubbleH + bottomBubbleH + bottomMergeH + bubbleHieght + 220;
}
- (void) changeTextFieldPoistion {
//TextFieldHight = 30
[_typeRef setFrame:
CGRectMake(0,self.view.frame.size.height-keyBoardHeight-30
, _typeRef.frame.size.width, _typeRef.frame.size.height)];
[_myTableView setFrame:
CGRectMake(_myTableView.frame.origin.x, _myTableView.frame.origin.y
, 374, self.view.frame.size.height-_myTableView.frame.origin.y-keyBoardHeight-30)];
}
Pic1: Before Re-sizing
Pic2: After Re-sizing 1
I found the answer here
The problem was with the Cell Identifier
Before Code:
static NSString *simpleTableIdentifier = #"ChatSendTableViewCell";
ChatSendTableViewCell *cell =
(ChatSendTableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:simpleTableIdentifier owner:self options:nil];
cell = [nib objectAtIndex:0];
}
After Code:
static NSString *CellIdentifier1 = #"ChatSendTableViewCell";
UITableViewCell *cell;
if (indexPath.section == 0)
{
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier1];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
}
}
1 - when keyboard Appers Get keyboard size -
keyboardInfo = [notification userInfo];
kbSize = [[keyboardInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
2-if your chatTable Contains Any row -
whwre [messageList] is Number of Rows
if ([messageList count]) {
NSIndexPath *iPath = [NSIndexPath indexPathForRow:[messageList count]-1 inSection:0];
UITableViewCell *lastCell = [chatTable cellForRowAtIndexPath:iPath];
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, lastCell.frame.origin) ) {
CGRect bkgndRect = lastCell.superview.frame;
bkgndRect.size.height += kbSize.height;
[lastCell.superview setFrame:bkgndRect];
[chatTable setContentOffset:CGPointMake(0.0,(lastCell.frame.origin.y+lastCell.frame.size.height) - (kbSize.height)) animated:NO];
}
}

Counting UITableView ContentView height is not always correct

I'm creating a messenger app, which displays a dialog between two people.
Parsing API response, I got text for inbox and outbox messages. Then I create a cell, using a UITableViewCell prototype from the storyboard.
All constraints are adjusted correctly.
The problem is that I use
[self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:NO];
to scroll the tableView to the bottom to have the last message in focus but the contentView of the upper cells is not counted at this time.
So i had to count height of cell before it is displayed. For this i use
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
RJMessageCell *cell = [self configureBasicCellAtIndexPath:indexPath];
[cell setNeedsLayout];
[cell layoutIfNeeded];
CGSize maximumSize = CGSizeMake(320.0, UILayoutFittingCompressedSize.height);
CGFloat height = [cell.contentView systemLayoutSizeFittingSize:maximumSize].height;
return height;
}
- (RJMessageCell *)configureBasicCellAtIndexPath:(NSIndexPath *)indexPath {
static NSString *inboxIdentifier = #"Inbox";
static NSString *outboxIdentifier = #"Outbox";
NSString *identifier;
RJMessage *message = [[[self.messageSectionsArray objectAtIndex:indexPath.section] messages] objectAtIndex:indexPath.row];
if (message.messageIsMine) {
identifier = outboxIdentifier;
} else {
identifier = inboxIdentifier;
}
RJMessageCell *cell = [self.tableView dequeueReusableCellWithIdentifier:identifier];
cell.messageView.layer.cornerRadius = 10.f;
cell.messageView.clipsToBounds = YES;
if ([message.text isEqualToString:#""]) {
cell.messageTextLabel.text = #" ";
} else {
cell.messageTextLabel.text = message.text;
}
cell.messageTextLabel.numberOfLines = 0;
cell.messageTextLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.timeLabel.text = [self stringTimeFromTimeInterval:message.messageInterval];
if (message.messageState == RJMessageStateUnread) {
cell.backgroundColor = [UIColor colorWithRed:151/255.0 green:200/255.0 blue:255/255.0 alpha:0.4];
} else {
cell.backgroundColor = [UIColor clearColor];
}
return cell;
}
Also the UILabel on screenshots are custom, to setBounds to label
- (void)setBounds:(CGRect)bounds {
[super setBounds:bounds];
if (self.numberOfLines == 0 && bounds.size.width != self.preferredMaxLayoutWidth) {
self.preferredMaxLayoutWidth = self.bounds.size.width;
[self setNeedsUpdateConstraints];
}
}
And the last thing i do, adding estimatedRowHeight in viewDidLoad
self.tableView.estimatedRowHeight = self.tableView.rowHeight;
self.tableView.rowHeight = UITableViewAutomaticDimension;
The first time they appear everything looks good, but when I scroll the table up and down, my cells change their size randomly.
What's wrong with the cell height?
You have to return Height by calculating the text width & height which you want to place inside the cell.
//Height For Row at index path
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellText = [NSString stringWithFormat:#"%#",[arrDataSource[indexPath.row]]];
UIFont *cellFont = [UIFont fontWithName:#"Helvetica" size:15.0];
NSAttributedString *attributedText =
[[NSAttributedString alloc]
initWithString:cellText
attributes:#
{
NSFontAttributeName: cellFont
}];
CGRect rect = [attributedText boundingRectWithSize:CGSizeMake(tableView.bounds.size.width - 90.0, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
return rect.size.height + 42;
}

Label's frame size does not change in tableView cell

I am working in storyboard. I have View Controller inherited from tableViewVC. In that vc I have cells with one or 2 lines of text. If I have one line, I just assign text to a custom textLabel in custom Cell. If I have 2 lines, I resize the labels frame. But it does not work when the table is loaded. I can see my resized labels in cell only after I scroll tableView up/down. How can I fix it?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
OptionItem *item = _currentOptionsList[indexPath.row];
static NSString *CellIdentifier = #"OptionSimpleCellIdentifier";
OptionSimpleCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.titleLabel.text = item.title;
cell.haveDetail = item.haveDetailItems;
cell.selectedSimpleOption = item.simpleSelected;
if (item.haveSelectedDetailItem)
{
cell.detailLabel.text = [item.detailItems[item.indexOfSelecteDetaildItem] title];
} else {
cell.detailLabel.text = nil;
cell.detailImageView.image = nil;
}
CGFloat textHeight = [Calculatons getLabelHeightForText:item.title andWidth:225 withFont:kFontListCell withMaxHeight:0];//19 - 39
CGRect rect = cell.titleLabel.frame;
NSLog(#"textHeight = %f cell.height = %f titleLabel.height %f \n",textHeight, cell.frame.size.height, cell.titleLabel.frame.size.height);
if (textHeight > 21)
{
rect.size.height = 41;
cell.titleLabel.frame = rect;
}
//nothing of this not works
[cell.titleLabel layoutIfNeeded];
[cell.titleLabel setNeedsLayout];
[cell.titleLabel setNeedsUpdateConstraints];
[cell.titleLabel setNumberOfLines:0];
return cell;
}
http://s23.postimg.org/8tszefzbf/Screen_Shot_2014_08_27_at_10_01_10_PM.png
After the first screen, i push the VS. second screen is what is shown after i scroll the table up and down.
I need second screen as a result after i push VC.
try using this earlier in the code, right after the cell is initialised instead of after the value is set to the label.
CGFloat textHeight = [Calculatons getLabelHeightForText:item.title andWidth:225 withFont:kFontListCell withMaxHeight:0];//19 - 39
CGRect rect = cell.titleLabel.frame;
NSLog(#"textHeight = %f cell.height = %f titleLabel.height %f \n",textHeight, cell.frame.size.height, cell.titleLabel.frame.size.height);
if (textHeight > 21)
{
rect.size.height = 41;
cell.titleLabel.frame = rect;
}

Multi-line UILabel

I've looked over older questions and tried all the suggestions, but still cannot seem to get a multi-line UILabel to work. I have a UITableView and the cell is created by tableView:cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *fieldValue = [self fieldValueAtIndexPath:indexPath];
NSString *fieldName = [self fieldNameAtIndexPath:indexPath];
NSString *title = [[self appDelegate] displayNameForFieldName:fieldName];
Field fieldCode = [[self appDelegate] fieldCodeForFieldName:fieldName];
DetailCell *cell = nil;
NSString *identifier = nil;
BOOL isNotes = [fieldName caseInsensitiveCompare:#"Notes"] == NSOrderedSame;
switch( isNotes ) {
case NO:
{
identifier = #"DetailCell";
cell = (DetailCell*)[tableView dequeueReusableCellWithIdentifier:identifier];
NSInteger rows = [self heightForText:fieldValue andFont:[self textFont] andWidth:cell.value.frame.size.width] / _oneRowSize.height;
cell.value.text = fieldValue;
cell.name.text = [title lowercaseString];
cell.name.numberOfLines = MAX( 1, rows );
cell.value.numberOfLines = cell.name.numberOfLines;
break;
}
case YES:
{
cell = (DetailCell *)[tableView dequeueReusableCellWithIdentifier:#"DetailCellNotes" forIndexPath:indexPath];
// cell = (DetailCell *)[tableView dequeueReusableCellWithIdentifier:#"DetailCellNotes"];
cell.value.text = #"This is a very long line of text which should take up several lines";
cell.name.text = [title lowercaseString];
cell.value.numberOfLines = 5; // No more than 5 lines of text
cell.value.backgroundColor = [UIColor purpleColor];
cell.value.lineBreakMode = NSLineBreakByWordWrapping;
cell.value.frame = CGRectMake(cell.value.frame.origin.x, cell.value.frame.origin.y, 180, 70);
[cell.value sizeThatFits:CGSizeMake(180., 70.)];
break;
}
}
cell.fieldName = fieldName;
return cell;
}
The height in the table view is defined like so
- (CGFloat) tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
NSString *fieldName = [self fieldNameAtIndexPath:indexPath];
CGFloat height = 0.0;
if([fieldName isEqualToString:#"Notes"])
{
height = 70.;
}
else if([fieldName isEqualToString:#"Image"])
{
height = 100.;
};
return height;
}
which makes the cell large enough to hold a 3-line label. However when the cell appears the label is only one line (shown by the background being purple).
The tableview uses prototype cells, and I've also tried to set it to numberOfLines=5 and WordWrapping, but that didn't change the effects either. I've also tried both of the commented out lines (though searches suggest that sizeToFit might actually reset numberOfLines to 1).
I wonder what I've missed. I can't see any other place where the it might be overridden.
Thanks.
You are calling dequeueReusableCellWithIdentifier: to create your cell. This is a mistake, because it means that the cell has not assumed its final size. It is much better to call dequeueReusableCellWithIdentifier:forIndexPath:. This means that the cell will actually have the height that you are giving it in heightForRowAtIndexPath:. You should then be able to set the height of the label successfully.

tableview's uitableviewcell display in worng order and duplicate rows

This is a chat app, I'm using tableview to display the chatting data between user and others, however I'v got Rows are displayed multiple(duplicate). The code is below:
#define kMyTag 1
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *messageDic = [self.chatArray objectAtIndex:indexPath.row];
if ([[messageDic objectForKey:#"myself"]boolValue] == false) {
static NSString *CellIdentifier = #"MessageChatFriendCell";
MessageChatFriendCell *cell = (MessageChatFriendCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[MessageChatFriendCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *chatInfo = [self.chatArray objectAtIndex:[indexPath row]];
UIView *chatView = [chatInfo objectForKey:#"view"];
chatView.tag = kMyTag;
[cell.contentView addSubview:chatView];
return cell;
} else {
static NSString *CellIdentifier = #"MessageChatSelfCell";
MessageChatSelfCell *cell = (MessageChatSelfCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[MessageChatSelfCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *chatInfo = [self.chatArray objectAtIndex:[indexPath row]];
UIView *chatView = [chatInfo objectForKey:#"view"];
chatView.tag = kMyTag;
[cell.contentView addSubview:chatView];
return cell;
}
}
the print results for each row are:
2012-08-02 15:44:47.152 MessageChatSelfCell-><UIView: 0x222790; frame = (85 0; 230 114); tag = 1; layer = <CALayer: 0x222320>>
2012-08-02 15:44:47.166 MessageChatFriendCell-><UIView: 0x21d790; frame = (0 0; 210 132); tag = 1; layer = <CALayer: 0x21d5c0>>
2012-08-02 15:44:47.176 MessageChatFriendCell-><UIView: 0x21bde0; frame = (0 0; 177 60); tag = 1; layer = <CALayer: 0x21be10>>
2012-08-02 15:44:47.183 MessageChatSelfCell-><UIView: 0x216430; frame = (85 0; 230 168); tag = 1; layer = <CALayer: 0x215fc0>>
2012-08-02 15:44:59.232 MessageChatFriendCell-><UIView: 0x215150; frame = (0 0; 86 60); tag = 1; layer = <CALayer: 0x214eb0>>
2012-08-02 15:45:00.465 MessageChatSelfCell-><UIView: 0x213220; frame = (85 0; 230 78); tag = 1; layer = <CALayer: 0x213250>>
Please advise, thanks!
Updated 2012-08-08
#define WRITER_NAME_LABEL_TAG 4
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MessageChatSelfCellIdentifier = #"MessageChatSelfCell";
static NSString *MessageChatFriendCellIdentifier = #"MessageChatFriendCell";
UITableViewCell *cell = nil;
UIView *chatView = nil;
NSDictionary *messageDic = [self.chatArray objectAtIndex:indexPath.row];
NSString *text = [messageDic objectForKey:#"compiled"];
BOOL myMessage = [[messageDic objectForKey:#"myself"] boolValue];
if (myMessage) {
cell = [tableView dequeueReusableCellWithIdentifier:MessageChatSelfCellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:MessageChatSelfCellIdentifier];
chatView = [self bubbleView:[NSString stringWithFormat:#"%#", text]
from:YES];
chatView.tag = WRITER_NAME_LABEL_TAG;
NSLog(#"MessageChatFriendCell->%#",chatView);
[cell addSubview:chatView];
}else {
chatView = (UIView *)[cell viewWithTag:WRITER_NAME_LABEL_TAG];
}
} else {
cell = [tableView dequeueReusableCellWithIdentifier:MessageChatFriendCellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:MessageChatFriendCellIdentifier];
NSString *text = [messageDic objectForKey:#"compiled"];
UIView *chatView = [self bubbleView:[NSString stringWithFormat:#"%#", text]
from:NO];
chatView.tag = WRITER_NAME_LABEL_TAG;
NSLog(#"MessageChatSelfCell->%#",chatView);
[cell addSubview:chatView];
}else {
chatView = (UIView *)[cell viewWithTag:WRITER_NAME_LABEL_TAG];
}
}
return cell;
}
I answered your another question How to calculate the Width and Height of NSString on UILabel
They are similar problem. the code below I C&P from the other question.
That's because you did not reuse the table cell, the structure should be like:
NSString *text = [messageInfo objectForKey:#"compiled"];
if(cell == nil)
{
writerNameLabel.numberOfLines = 0;
writerNameLabel.textAlignment = UITextAlignmentRight;
writerNameLabel.backgroundColor = [UIColor clearColor];
[cell addSubview:writerNameLabel];
}
else {
writerNameLabel = (UILabel *)[cell viewWithTag:WRITER_NAME_LABEL_TAG];
}
CGSize constraint = CGSizeMake(296,9999);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE]
constrainedToSize:constraint
lineBreakMode:UILineBreakModeWordWrap];
[writerNameLabel setFrame:CGRectMake(writerNameLabel.frame.origin.x, writerNameLabel.frame.origin.y, size.width, size.height)];
I've been gone through and answered some of your question, that's correct way to write your tableview controller. And your problem will be solved.
Few things u should change, first don't store your views in chatInfo instead store your data.
Next add the view to the cell only when u create new cell, otherwise u will add more then one view to a reused cell.
Take a look at the example below, here I'm creating a cell with the message writer name, for my messages the writer name will be in the right hand side, and for my friend messages it will be on the left.
Pay attention that I'm only add the writer name label when I create a new cell, then I give it a tag so I can get the label next time I want to change it.
#define WRITER_NAME_LABEL_TAG 1
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MessageChatFriendCellIdentifier = #"MessageChatFriendCell";
static NSString *MessageChatSelfCellIdentifier = #"MessageChatSelfCell";
UITableViewCell *cell = nil;
UILabel *writerNameLabel = nil;
NSDictionary *messageInfo = [self.chatArray objectAtIndex:indexPath.row];
BOOL myMessage = [[messageInfo objectForKey:#"myself"] boolValue];
if (myMessage) {
// this is my message
cell = [tableView dequeueReusableCellWithIdentifier:MessageChatSelfCellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:MessageChatSelfCellIdentifier] autorelease];
writerNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 20)];
writerNameLabel.tag = WRITER_NAME_LABEL_TAG;
writerNameLabel.textAlignment = UITextAlignmentRight;
[cell addSubview:writerNameLabel];
}
else {
writerNameLabel = (UILabel *)[cell viewWithTag:WRITER_NAME_LABEL_TAG];
}
}
else {
// this is my friend message
cell = [tableView dequeueReusableCellWithIdentifier:MessageChatFriendCellIdentifier];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:MessageChatFriendCellIdentifier] autorelease];
writerNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 20)];
writerNameLabel.tag = WRITER_NAME_LABEL_TAG;
writerNameLabel.textAlignment = UITextAlignmentLeft;
[cell addSubview:writerNameLabel];
}
else {
writerNameLabel = (UILabel *)[cell viewWithTag:WRITER_NAME_LABEL_TAG];
}
}
// get the current writer name from the model
NSString *writerName = [messageInfo objectForKey:#"writer"];
// configure cell...
writerNameLabel.text = writerName;
return cell;
}

Resources