To make the label expand with the cell, you should give it constraints that tie it to the views above and below -- in you case that looks like a constraint to the bottom of the cell, and one to the label (with "Titel...") above it.
Label in dynamic cell height on table view not showing text properly
-
29-08-2022 - |
Frage
I'm trying to get my table view cells to adjust their heights based on the content inside the cells.
It seems to be working since the cells have different heights, but I'm having trouble with displaying the text properly.
The table view and the prototype cell is created with storyboard and I have a custom cell class linked to my prototype cell. In my prototype cell I have three labels; Title label, date label and a label that has the dynamic text data. The dynamic text data labels line numbers are set to 0 and line break is set to "Word wrapping" in the storyboard's attributes inspector.
When I run the app the cell heights are all different so I assume the height for row at index path works:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Text data
NSDictionary *cellOutputDict = [newsDataArray objectAtIndex:indexPath.row];
NSString *text = [NSString stringWithFormat:@"%@", [cellOutputDict objectForKey:@"text"]];
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:nil];
CGFloat width = 280;
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX}
options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
CGSize size = rect.size;
return size.height + 2 * 20; // size.height plus 2 times the desired margin
}
And this is my cell for row at index path:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"NewsCell";
NewsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// If the cell doesn't exists create it
if (cell == nil) {
cell = [[NewsCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// Configure the cell...
// Text data
NSDictionary *cellOutputDict = [newsDataArray objectAtIndex:indexPath.row];
cell.titleLabel.text = [NSString stringWithFormat:@"%@", [cellOutputDict objectForKey:@"title"]];
cell.dateLabel.text = [NSString stringWithFormat:@"%@", [cellOutputDict objectForKey:@"date"]];
cell.newsTextLabel.text = [NSString stringWithFormat:@"%@", [cellOutputDict objectForKey:@"text"]];
return cell;
}
The cell.newsTextLabel.text that prints out the dynamic text data is displayed in the cell, but only the first line.
I've tried some examples of displaying dynamic cell heights for iOS 6.1 and they work fine but I can't get it to work on iOS 7+
So I hope someone can help with this and help me to figure out what I'm doing wrong.
Lösung
Andere Tipps
try this
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
float height = cell.frame.size.height;
return height;
}
To set automatic dimension for row height & estimated row height, ensure following steps to make, auto dimension effective for cell/row height layout.
- Assign and implement tableview dataSource and delegate
- Assign
UITableViewAutomaticDimension
to rowHeight & estimatedRowHeight - Implement delegate/dataSource methods (i.e.
heightForRowAt
and return a valueUITableViewAutomaticDimension
to it)
-
Objective C:
// in ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
@property IBOutlet UITableView * table;
@end
// in ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.table.dataSource = self;
self.table.delegate = self;
self.table.rowHeight = UITableViewAutomaticDimension;
self.table.estimatedRowHeight = UITableViewAutomaticDimension;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
Swift:
@IBOutlet weak var table: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Don't forget to set dataSource and delegate for table
table.dataSource = self
table.delegate = self
// Set automatic dimensions for row height
// Swift 4.2 onwards
table.rowHeight = UITableView.automaticDimension
table.estimatedRowHeight = UITableView.automaticDimension
// Swift 4.1 and below
table.rowHeight = UITableViewAutomaticDimension
table.estimatedRowHeight = UITableViewAutomaticDimension
}
// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
// Swift 4.2 onwards
return UITableView.automaticDimension
// Swift 4.1 and below
return UITableViewAutomaticDimension
}
For label instance in UITableviewCell
- Set number of lines = 0 (& line break mode = truncate tail)
- Set all constraints (top, bottom, right left) with respect to its superview/ cell container.
- Optional: Set minimum height for label, if you want minimum vertical area covered by label, even if there is no data.
Note: If you've more than one labels (UIElements) with dynamic length, which should be adjusted according to its content size: Adjust 'Content Hugging and Compression Resistance Priority` for labels which you want to expand/compress with higher priority.
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByClipping;