How to calculate the required height of a dynamically configured UITableViewCells based on NSString

I have a UITableView that has custom UITableViewCells that are user comments. Right now I have cells with a height of 115.0 feet, but I want the height to vary depending on how long the comment lasts. If a comment has more than three lines, I want the user to be able to select a cell, and the cell for the extension displays the entire comment. I use the [UIView animateWithDuration: completion: method to expand the cell, but I do not know how to determine the correct cell size, which should be based on the duration of the text. Can anybody help me? Here is the code:

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 0) { return 480; } else { if (self.cellType == 0) { return 115; } else { return 75; } } } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row > 0) { NSIndexPath *path = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section]; UITableViewCell *cell = [tableView cellForRowAtIndexPath:path]; if ([cell isKindOfClass:[CommentCell class]]) { CommentCell *cell = (CommentCell *)[tableView cellForRowAtIndexPath:indexPath]; UILabel *label = cell.commentBodyLabel; NSString *theText = label.text; CGSize constraintSize = CGSizeMake(label.frame.size.width, label.frame.size.height); CGSize labelSize = [theText sizeWithFont:label.font constrainedToSize:constraintSize lineBreakMode:label.lineBreakMode]; CGFloat labelHeight = labelSize.height; int numLines = (int)(labelHeight/label.font.leading); NSLog(@"there are %i lines", numLines); NSLog(@"The text height is %f", labelHeight); if (numLines == 3) { //This is where I should expand the cell } } 
+4
source share
2 answers

Take a look at NSString UIKit Add-ons

You are particularly interested in sizeWithFont:constrainedToSize:lineBreakMode:

Set the CGSize.width property of the constrainedToSize property to the width of your cell / label area. And then set CGSize.height to a very large number, possibly CGFLOAT_MAX . The idea is that you say, β€œHey, this label should correspond to an area that is static width, but it can extend vertically forever. So, tell me how high this label will actually be provided the information I gave you. "

 NSString *comment = @"Some really long comment that does not fit in the standard cell size. This comment will be wrapped by word. Some more words to make this longer..."; CGSize renderedSize = [comment sizeWithFont:myFont constrainedToSize:CGSizeMake(kCellWidth, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping]; 

renderedSize.height is the value you will return for (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

+1
source

One method is to instantiate cell prototypes and calculate their dynamic height based on the data. This method allows you to rely on the storyboard layout (if you use storyboards) without having to hardcode the configuration information of your cell in the view controller.

EDIT I added a working example of cells with dynamic height labels using TLIndexPathTools , which automatically calculates dynamic heights for you if your cell implements the TLDynamicHeightView protocol. See Dynamic Height project. The height calculation is performed in the cell as follows:

 @interface DynamicHeightCell () @property (nonatomic) CGSize originalSize; @property (nonatomic) CGSize originalLabelSize; @end @implementation DynamicHeightCell - (void)awakeFromNib { [super awakeFromNib]; self.originalSize = self.bounds.size; self.originalLabelSize = self.label.bounds.size; } - (void)configureWithText:(NSString *)text { self.label.text = text; [self.label sizeToFit]; } #pragma mark - TLDynamicSizeView - (CGSize)sizeWithData:(id)data { [self configureWithText:data]; CGSize labelSize = self.label.bounds.size; CGSize size = self.originalSize; size.width += labelSize.width - self.originalLabelSize.width; size.height += labelSize.height - self.originalLabelSize.height; return size; } @end 

In essence, you remember the original dimensions when the cell wakes up from the storyboard. Then, when the calculation is done, call sizeToFit on the label and use the new size to calculate the height delta and add it to the original height. In the storyboard, you need to set the label width to the desired width and set the number lines to 0.

On the view controller side, if you are using TLIndexPathTools , you just need to customize the data model with an array of strings and set the label on the cells. Prototype and size calculations are performed automatically by the TLTableViewController base class. If you do not want to use TLIndexPathTools , you must draw the bits from the TLTableViewController .

 @implementation DynamicHeightTableViewController - (void)viewDidLoad { [super viewDidLoad]; self.indexPathController.items = @[ @"Lorem ipsum dolor sit amet, consectetur adipiscing elit.", @"Fusce ac erat at lectus pulvinar porttitor vitae in mauris. Nam non eleifend tortor.", @"Quisque tincidunt rhoncus pellentesque.", @"Duis mauris nunc, fringilla nec elementum nec, lacinia at turpis. Duis mauris nunc, fringilla nec elementum nec, lacinia at turpis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.", ]; } - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { NSString *item = [self.indexPathController.dataModel itemAtIndexPath:indexPath]; DynamicHeightCell *dynamicCell = (DynamicHeightCell *)cell; [dynamicCell configureWithText:item]; } 
+1
source

Source: https://habr.com/ru/post/1483857/


All Articles