UITableViewCell с динамической высотой iOS
Я внедрил TableView с CustomCell в своем приложении,
Я хочу динамическую высоту моего UITableViewCell
в соответствии с длиной текста в UITableViewCell
,
вот снимок Customcell
:
и вот снимок моего UITableView
:
фрагмент кода для heightForRowAtIndexPath
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 320.0f
#define CELL_CONTENT_MARGIN 10.0f
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
NSString *text = [DescArr objectAtIndex:[indexPath row]];
CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
CGFloat height = MAX(size.height, 100.0);
return height;
}
Как вы можете видеть на втором изображении, высота для ячейки фиксирована, она не изменяет с ней размер текста (контента).
Где я делаю ошибку? Как я могу сделать ярлык или ячейку для обновления своего размера в соответствии со своим содержимым/текстом?
Ответы
Ответ 1
Следующий код работал отлично для меня. Постарайтесь с этим
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
CGFloat lRetval = 10;
CGSize maximumLabelSize = CGSizeMake(231, FLT_MAX);
CGSize expectedLabelSize;
CGFloat numberoflines = [thirdcellText length]/17.0;
if (indexPath.section == 0) {
expectedLabelSize = [firstcellText sizeWithFont:[UIFont systemFontOfSize:16.0]
constrainedToSize:maximumLabelSize
lineBreakMode:NSLineBreakByWordWrapping];
lRetval = expectedLabelSize.height;
}
else if(indexPath.section == 1)
{
expectedLabelSize = [secondcellText sizeWithFont:[UIFont systemFontOfSize:16.0]
constrainedToSize:maximumLabelSize
lineBreakMode:NSLineBreakByWordWrapping];
lRetval = expectedLabelSize.height;
}
else if (indexPath.section == 2)
{
expectedLabelSize = [thirdcellText sizeWithFont:[UIFont systemFontOfSize:16.0]
constrainedToSize:CGSizeMake(231, numberoflines*17.0)
lineBreakMode:NSLineBreakByWordWrapping];
lRetval = expectedLabelSize.height-128.0;
}
UIImage *factoryImage = [UIImage imageNamed:NSLocalizedString(@"barcode_factory_reset.png", @"")];
CGFloat height = factoryImage.size.height;
if (lRetval < height) {
lRetval = height+15.0;
}
return lRetval;
}
Попробуйте добавить следующий код в свой метод autolayout класса customcell
textview.frame = frame;
CGRect frame1 = textview.frame;
frame1.size.height = textview.contentSize.height-2;
textview.frame = frame1;
textview.contentSize = CGSizeMake(textview.frame.size.width, textview.frame.size.height);
labelPtr.frame = CGRectMake(CGRectGetMinX(imageView.frame)+CGRectGetMaxX(imageView.frame)+5.0, textview.frame.size.height+10.0, 140, 16.0);
[labelPtr setNeedsDisplayInRect:labelPtr.frame];
Попробуйте установить свойства метки следующим образом
labelPtr = [[UILabel alloc] initWithFrame:CGRectZero];
labelPtr.backgroundColor =[UIColor clearColor];
[labelPtr setNeedsLayout];
[labelPtr setNeedsDisplay];
[self.contentView addSubview:labelPtr];
Ответ 2
Пожалуйста, посмотрите ЗДЕСЬ - Учебник по динамическому табуляции таблицы и автоматической компоновке.
Что вам нужно:
- установить требуемое ограничение на элементы в ячейке (make shure, чтобы все было сделано правильно, если нет - вы можете получить много проблем). Также сделайте так, чтобы вы установили значение IntrinsicSize в значение PlaceHolder
![enter image description here]()
- добавить несколько методов для вычисления размера ячейки
Методы:
//this will calculate required height for your cell
-(CGFloat)heightForBasicCellAtIndexPath:(NSIndexPath *)indexPath {
static UIYourClassCellName *sizingCell = nil;
//create just once per programm launching
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sizingCell = [self.tableView dequeueReusableCellWithIdentifier:@"identifierOfCell"];
});
[self configureBasicCell:sizingCell atIndexPath:indexPath];
return [self calculateHeightForConfiguredSizingCell:sizingCell];
}
//this method will calculate required height of cell
- (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell {
[sizingCell setNeedsLayout];
[sizingCell layoutIfNeeded];
CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height;
}
И вызовите
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return [self heightForBasicCellAtIndexPath:indexPath];
}
Конфигурация ячейки
- (void)configureBasicCell:(RWBasicCell *)cell atIndexPath:(NSIndexPath *)indexPath {
//make some configuration for your cell
}
После каждой операции я получил следующий (текст внутри ячейки только как заполнитель):
![enter image description here]()
Ответ 3
Долгое время искал, как правильно определять высоту ячейки, - выглядит как лучшее решение, boundingRectWithSize и constrainedToSize часто неправильно рассчитанная высота текста, вам нужно создать UILabel, чем использовать функцию sizeThatFits, см. ниже
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(8, 5, celllabelWidth, 9999)];
label.numberOfLines=0;
label.font = [UIFont fontWithName:fontName size:textSize];
label.text = @"celllabelTextHere";
CGSize maximumLabelSize = CGSizeMake(celllabelWidth, 9999);
CGSize expectedSize = [label sizeThatFits:maximumLabelSize];
return expectedSize.height;
}
Ответ 4
Я видел много решений, но все было не так или не было.
Вы можете решить все проблемы с 5 строками в viewDidLoad и автозапуском.
Это для объекта C:
_tableView.delegate = self;
_tableView.dataSource = self;
self.tableView.estimatedRowHeight = 80;//the estimatedRowHeight but if is more this autoincremented with autolayout
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0) ;
Для быстрого 2.0:
self.tableView.estimatedRowHeight = 80
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.setNeedsLayout()
self.tableView.layoutIfNeeded()
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0)
Теперь создайте свою ячейку с помощью xib или в виде таблицы в вашей раскадровке
При этом вам не нужно ничего больше или переопределять. (Don forget number os lines 0) и нижняя метка (ограничение) понизить "Приоритет обхода контента - по вертикали до 250"
![введите описание изображения здесь]()
Вы можете загрузить код в следующем URL-адресе:
https://github.com/jposes22/exampleTableCellCustomHeight
Ссылки: http://candycode.io/automatically-resizing-uitableviewcells-with-dynamic-text-height-using-auto-layout/
Ответ 5
Это очень просто сейчас
Используйте следующие шаги
- Установите ограничение на метку (если используется пользовательская ячейка)
- Число строк должно быть 0
- Настройка нескольких свойств UITableView
self.tableView.estimatedRowHeight = 100.0;
self.tableView.rowHeight = UITableViewAutomaticDimension;
Наслаждайтесь:)
Для более подробной информации вы можете проверить
www.raywenderlich.com
fooobar.com/questions/1017/...
Ответ 6
Не могли бы вы попробовать:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
int topPadding = cell.yourLabel.frame.origin.x;
int bottomPadding = cell.frame.size.heigth-(topPadding+cell.yourLabel.frame.size.height);
NSString *text = [DescArr objectAtIndex:[indexPath row]];
CGSize maximumSize = CGSizeMake(cell.yourLabel.frame.size.width, 9999);
CGSize expectedSize = [text sizeWithFont:yourCell.yourLabel.font constrainedToSize:maximumSize lineBreakMode:yourCell.yourLabel.lineBreakMode];
return topPadding+expectedSize.height+bottomPadding;
}
Ответ 7
Обратитесь к этой ссылке, которую вы используете Autolayout
else вы можете использовать подход ниже
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NewsVCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
if (cell == nil)
{
cell = [[NewsVCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}
cell.titleCell.numberOfLines = 0;
cell.descriptionCell.numberOfLines = 0;
cell.titleCell.font = [UIFont systemFontOfSize:12.0f];
cell.descriptionCell.font = [UIFont systemFontOfSize:12.0f];
cell.descriptionCell.textColor = [UIColor lightGrayColor];
CGSize maximumLabelSize;
if([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad || [[[UIDevice currentDevice] model] isEqualToString:@"iPad Simulator"])
{
maximumLabelSize = CGSizeMake(768, 10000);
}
else
{
maximumLabelSize = CGSizeMake(270, 10000);
}
NSString *newsTitle = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
NSString *descriptionsText = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"];
CGSize expectedTitleLabelSize = [newsTitle sizeWithFont: cell.titleCell.font constrainedToSize:maximumLabelSize lineBreakMode:cell.titleCell.lineBreakMode];
CGSize expectedDescriptionLabelSize = [descriptionsText sizeWithFont:cell.descriptionCell.font constrainedToSize:maximumLabelSize lineBreakMode:cell.descriptionCell.lineBreakMode];
NSLog(@"cellForRowAtIndexPath :indexpath.row %d: height expectedTitleLabelSize:%f , indexpath.row height expectedDescriptionLabelSize:%f",indexPath.row,expectedTitleLabelSize.height,expectedDescriptionLabelSize.height);
if (newsTitle.length > 0)
{
cell.titleCell.frame = CGRectMake(20.0f, 10.0f, 270.0f ,expectedTitleLabelSize.height+20.0f);
}
else
{
cell.titleCell.frame = CGRectMake(20.0f, 10.0f, 270.0f ,expectedTitleLabelSize.height-20.0f);
}
if (descriptionText.length > 0)
{
cell.descriptionCell.frame = CGRectMake(20.0f, 10.0f + cell.titleCell.frame.size.height, 270.0f, expectedDescriptionLabelSize.height+20.0f);
}
else
{
cell.descriptionCell.frame = CGRectMake(20.0f, cell.titleCell.frame.size.height, 270.0f, 0.0f);
}
cell.descriptionCell.frame = CGRectMake(20.0f, 10.0f + cell.titleCell.frame.size.height, 270.0f, expectedDescriptionLabelSize.height+20.0f);
cell.titleCell.text = newsTitle;
cell.descriptionCell.text = descriptionsText;
NSLog(@"indexpath.row %d :title %@ ",indexPath.row,newsTitle);
NSLog(@"indexpath.row %d :description %@",indexPath.row,descriptionsText);
return cell;
}
знак прагмы - UITableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
float totalHeight = 0.0f;
UILabel *labelTitle;
CGSize maximumLabelSize;
if([UIDevice currentDevice].userInterfaceIdiom==UIUserInterfaceIdiomPad || [[[UIDevice currentDevice] model] isEqualToString:@"iPad Simulator"])
{
labelTitle = [[UILabel alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 692.0f, 20.0f)]; // iPad
maximumLabelSize = CGSizeMake(768.0f, 10000.0f);
}
else
{
labelTitle = [[UILabel alloc]initWithFrame:CGRectMake(0.0f, 0.0f, 270.0f, 20.0f)];
maximumLabelSize = CGSizeMake(270.0f, 10000.0f);
}
labelTitle.font = [UIFont systemFontOfSize:12.0f];
NSString *newsTitle;
NSString *newsDescription;
// cell.titleCell.text = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
// cell.descriptionCell.text = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"];
newsTitle = [[feeds objectAtIndex:indexPath.row] objectForKey: @"title"];
newsDescription = [[feeds objectAtIndex:indexPath.row] objectForKey: @"description"];
NSLog(@"indexpath.row %d :newsDescription.length %d",indexPath.row,newsDescription.length);
CGSize expectedTitleLabelSize;
CGSize expectedDescriptionLabelSize;
if (newsTitle.length > 0)
{
expectedTitleLabelSize = [newsTitle sizeWithFont:labelTitle.font constrainedToSize:maximumLabelSize lineBreakMode:labelTitle.lineBreakMode];
totalHeight = totalHeight + 20.0f;
}
else
{
expectedTitleLabelSize = CGSizeMake(0.0f, 0.0f);
totalHeight = -20.0f;
}
if (newsDescription.length > 0)
{
expectedDescriptionLabelSize = [newsDescription sizeWithFont:labelTitle.font constrainedToSize:maximumLabelSize lineBreakMode:labelTitle.lineBreakMode];
totalHeight = totalHeight + 20.0f;
}
else
{
expectedDescriptionLabelSize = CGSizeMake(0.0f, 0.0f);
totalHeight = -20.0f;
}
// NSLog(@"question: %f title:%f",expectedQuestionLabelSize.height,expectedTitleLabelSize.height);
totalHeight = expectedDescriptionLabelSize.height + expectedTitleLabelSize.height + 30.0f+20.0f;
return totalHeight;
}
Ответ 8
Если вы хотите ограничить максимальную высоту до 100 pt, вы должны использовать MIN
вместо этого на MAX
:
CGFloat height = fmin(size.height, 100.0);
Ответ 9
Мне нужна была динамическая высота ячейки таблицы, основанная на количестве текста, который будет отображаться в этой ячейке. Я решил это так:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!isLoading)
{
if ([self.conditionsDataArray count]>0)
{
Conditions *condition =[self.conditionsDataArray objectAtIndex:indexPath.row];
int height;
UITextView *textview = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 236, 0)]; //you can set your frame according to your need
textview.text = condition.comment;
textview.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[tableView addSubview:textview];
textview.hidden = YES;
height = textview.contentSize.height;
NSLog(@"TEXT VIEW HEIGHT %f", textview.contentSize.height);
[textview removeFromSuperview];
[textview release];
return height;
}
return 55; //Default height, if data is in loading state
}
Обратите внимание, что Text View был добавлен как Subview, а затем скрыт, поэтому убедитесь, что вы добавили его как SubView, иначе высота не будет рассмотрена.
Ответ 10
Я только что написал об этой проблеме и подходе, который я, наконец, выбрал. Вы можете прочитать об этом здесь: Динамическая высота ячейки UITableView на основе содержимого
В принципе, я создал подкласс UITableView, который обрабатывает все это как для стандартных, так и для пользовательских ячеек. Вероятно, это требует настройки, но я использовал его, как с хорошим результатом.
Вы можете получить код здесь: https://github.com/danielsaidi/DSTableViewWithDynamicHeight
Надеюсь, что это поможет (... и если это не так, я извиняюсь и хотел бы услышать, почему нет)
Ответ 11
Чтобы установить автоматический размер для высоты строки и оцениваемой высоты строки, выполните следующие шаги, чтобы сделать автоматическое измерение эффективным для раскладки высоты ячеек/строк.
- Присвоить и реализовать данные tableviewSource и делегировать
- Назначить
UITableViewAutomaticDimension
для rowHeight и measuredRowHeight
- Внедрить методы делегирования /dataSource (т.е.
heightForRowAt
и вернуть ему значение UITableViewAutomaticDimension
)
-
@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
table.rowHeight = UITableViewAutomaticDimension
table.estimatedRowHeight = UITableViewAutomaticDimension
}
// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
Для экземпляра ярлыка в UITableviewCell
- Установить количество строк = 0 (& режим прерывания строки = обрезать хвост)
- Задайте все ограничения (сверху, снизу, справа налево) относительно контейнера супервизора/ячейки.
- Необязательно: установите минимальную высоту для метки, если вы хотите, чтобы минимальная вертикальная область была покрыта меткой, даже если данных нет.
![enter image description here]()
Ответ 12
Попробуй, он работал как шарм! для меня,
В viewDidLoad напишите этот код
-(void)viewDidLoad
{
[super viewDidLoad];
self.tableView.estimatedRowHeight = 100.0; // for example. Set your average height
self.tableView.rowHeight = UITableViewAutomaticDimension;
}
В cellForRowAtIndexPath напишите этот код
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
}
cell.textLabel.numberOfLines = 0; // Set label number of line to 0
cell.textLabel.text=[[self.arForTable objectAtIndex:indexPath.row] valueForKey:@"menu"];
[cell.textLabel sizeToFit]; //set size to fit
return cell;
}
Надеюсь, что это поможет кому-то.