Reputation: 2438
I have a UITableView
with custom UITableViewCells
. The cell needs to be of different heights as per the text I receive from the server. I change the height accordingly as follows:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0)
return [self getHeightOfQuestion];
else if (indexPath.row == 1)
return 64.0f;
else // ****** this is the cell in question!
return [self getHeightOfAnswerAtIndexPath:indexPath];
return 300.0f;
}
]- (CGFloat) getHeightOfAnswerAtIndexPath:(NSIndexPath*) indexPath
{
CGRect answerFrame = CGRectZero;
if ([QXTUtility currentOsVersion] >= 7.0f)
{
answerFrame = [[[[self.answerDetails objectForKey:kAnswers] objectAtIndex:indexPath.row-2] objectForKey:kAnswerText] boundingRectWithSize:CGSizeMake(242.0f, 900.0f) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont fontWithName:@"Roboto-Light" size:14.0f]} context:nil];
}
else
{
CGSize answerSize = [[[[self.answerDetails objectForKey:kAnswers] objectAtIndex:indexPath.row-2] objectForKey:kAnswerText] sizeWithFont:[UIFont fontWithName:@"Roboto-Light" size:14.0f] constrainedToSize:CGSizeMake(242.0f, 500.0f) lineBreakMode:NSLineBreakByTruncatingTail];
answerFrame.size = answerSize;
}
NSLog(@"Frame %@", NSStringFromCGRect(answerFrame));
return answerFrame.size.height + 50;
}
It works fine on iOS6. But in iOS7, I get following output:
But if I scroll the UITableView again, the cell lays out perfectly like so:
Here's my cellForRowAtIndexPath
:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *answerCellIdentifier = @"QXTAnswerCell";
QXTAnswerCell *answerCell = (QXTAnswerCell *)[tableView dequeueReusableCellWithIdentifier:answerCellIdentifier];
if (answerCell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"QXTAnswerCell" owner:self options:nil];
answerCell = [nib objectAtIndex:0];
}
[self setDataToAnswerCell:answerCell AtIndexPath:indexPath];
[self layoutAnswerCell:answerCell AtIndexPath: indexPath];
[answerCell setNeedsLayout];
return answerCell;
}
- (void) layoutAnswerCell:(QXTAnswerCell*) answerCell
AtIndexPath:(NSIndexPath*) indexPath
{
CGRect answerCellFrame = answerCell.answer.frame;
answerCellFrame.origin.y = answerCell.name.frame.origin.y + answerCell.name.frame.size.height + 6;
if ([QXTUtility currentOsVersion] >= 7.0f)
{
answerCellFrame.size.height += 30.0f;
answerCell.answer.lineBreakMode = NSLineBreakByWordWrapping;
}
answerCell.answer.frame = answerCellFrame;
dispatch_async(dispatch_get_main_queue(), ^{
[answerCell setNeedsLayout];
});
}
Please help me out. I'm calling a reload data once the answer's data source is populated. Thanks.
UPDATE
Just found out the first reloadData
is not called once the answers are received from the server.
// Delegate from Network Class
- (void) answersReceivedWithDetails:(id)answerDetails
{
NSLog(@"Answer Details %@", answerDetails);
self.answerDetails = [[NSMutableDictionary alloc] initWithDictionary:answerDetails];
[self.tableView reloadData];
[self.tableView setNeedsDisplay];
}
Here's the constraints of the cell:
Upvotes: 3
Views: 197
Reputation: 2438
Here's what I did to solve my issue. There is some issue with boundingRectWithSize
and UILabels
created using IBOutlets. So I did the above and then assigned that to a UILabel
created using code and added that to the cell. And everything worked perfectly well!
- (void) layoutAnswerCell:(QXTAnswerCell*) answerCell
AtIndexPath:(NSIndexPath*) indexPath
{
if ([QXTUtility currentOsVersion] >= 7.0f)
{
[answerCell.answer removeFromSuperview];
NSString *answerString = <your string>
CGRect answerFrame = [answerString boundingRectWithSize:CGSizeMake(242.0f, 900.0f) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont fontWithName:@"Roboto-Light" size:14.0f]} context:nil];
answerFrame.origin.x = 20.0f;
answerFrame.origin.y = answerCell.name.frame.origin.y + answerCell.name.frame.size.height + 6;
answerFrame.size.height = ceilf(answerFrame.size.height);
answerFrame.size.height += 30.0f;
answerCell.answer.lineBreakMode = NSLineBreakByTruncatingTail;
answerCell.answer.frame = answerFrame;
UILabel *newLabel = [[UILabel alloc] initWithFrame:answerFrame];
[newLabel setFont:[UIFont fontWithName:@"Roboto-Light" size:14.0f]];
newLabel.text = answerString;
newLabel.numberOfLines = 0;
[answerCell.contentView addSubview:newLabel];
[answerCell setNeedsDisplay];
}
}
See if this works for anyone else. If that's the case I'll accept this answer. But it did get the job done for me.
Upvotes: 1
Reputation: 1779
I think the problem lies in returning the correct height in tableView:heightForRowAtIndexPath:
It is returning always 64.0f at indexPath.row = 1
static CGFloat answerCellDefaultHeight = 200.0f; //change this to the actual value of the height of the answer table cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0) {
return [self getHeightOfQuestion];
} else if (indexPath.row == 1) {
return 64.0f;
} else {
CGFloat computedHeight = [self getHeightOfAnswerAtIndexPath:indexPath];
return (computedHeight > answerCellDefaultHeight) ? computedHeight : answerCellDefaultHeight;
}
}
Upvotes: 0