There are several ways of doing this, but I've found that the most reliable is to use a temporary and invisible UITextView to get the necessary size.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Ideally you should do lazy loading so that instead of creating a new textView each time, you just reuse the same one.
UITextView *temp = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 44)]; //This initial size doesn't matter
temp.font = __Your_desired_font__
temp.text = @"Put your status here";
CGFloat textViewWidth = __your_constraint_width__
CGRect tempFrame = CGRectMake(0,0,textViewWidth,44); //The height of this frame doesn't matter.
CGSize tvsize = [temp sizeThatFits:CGSizeMake(tempFrame.size.width, tempFrame.size.height)]; //This calculates the necessary size so that all the text fits in the necessary width.
//Add the height of the other UI elements inside your cell
return tvsize.height + staticElementHeights
}
This works on iOS 7, but I think if you want to support iOS 6 you need to actually add the textView as a subview for this to work. Just set temp.hidden = YES
The way text is displayed in a UILabel is different from a UITextView, so for a UILabel, you should use the method described in this answer iOS auto adjust label height