Как стать автором
Обновить

Калькуляция высоты ячейки в динамической таблице UITableView

Время на прочтение3 мин
Количество просмотров10K
Всем доброго времени суток, недавно столкнулся с такой проблемой, что при записи текста (длинного текста) в ячейку таблицы, её Label не увеличивается пропорционально объёму текста, то есть если там 3 слова, то все хорошо, но если записать туда 3-4 предложения, то появится примерно вот такая штука.



Недельный поиск решения проблемы оказался все таки успешным и сегодня постараюсь объяснить вам, как именно решать данную проблему.

После того, как вы создали NavigationController, сделали свой ViewController наследником от UITableViewController'а, нам надо создать класс для нашей кастомной ячейки. Создаем новый класс называем его например customCell и указываем, что он наследник класса UITableViewCell.

#import "customCell.h"

@implementation customCell

- (void)awakeFromNib {
    // Initialization code
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

В файле *.m сразу создадутся 2 метода, которые в нашем случае нам не понадобятся.

Далее помещаем в наш прототип ячейки UILabel. Кликаем на него мышкой и устанавливаем такие настройки, важно, чтобы вот эти параметры были именно такими.



Lines = 0 говорит о том, что ячейка может иметь неограниченное количество строк, а Line Break = Word Wrap, что слова будут переноситься на новую строку, когда закончится место в этой. Но это еще не все, теперь нам надо связать наш UILabel с файлом customCell.h

После этого вернемся в файл ViewController и воспользуемся делегатом heightForRowAtIndexPath.

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

Можно проводить калькуляцию в этом делегате прямо в вашем ViewController'е, но я бы советовал перенести все это в customCell.m для экономии места в основном файле.

Перейдем в customCell.h и создадим метод с плюсиком.

+(CGFloat) heightForText:(NSString*) text;


И вернемся к файлу .m для его реализации.

Для того, чтобы ячейка посчитала высоту, нам нужно записать в NSDictionary атрибуты нашего текста, то есть его размер шрифта, отступы, параграфы, тени и тд. Далее вызвать метод, который посчитает нам все строки и выдаст общую высоту ячейки.

boundingRectWithSize

в него мы записываем длину ячейки, с отступами или без, высоту (если нужно ее ограничить) и «засунуть» вашу Dictionary с атрибутами. Пример кода ниже.

+(CGFloat) heightForText:(NSString*) text {
    
    CGFloat offset = 1.0;
    
    UIFont* font = [UIFont systemFontOfSize:17.f];
    
    NSMutableParagraphStyle* paragraph = [[NSMutableParagraphStyle alloc] init];
    [paragraph setLineBreakMode:NSLineBreakByWordWrapping];    
    
    NSDictionary* attributes =
    [NSDictionary dictionaryWithObjectsAndKeys:
     font , NSFontAttributeName,
     paragraph, NSParagraphStyleAttributeName, nil];
    
    CGRect rect = [text boundingRectWithSize:CGSizeMake(320 - 2 * offset, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context:nil];
    
    return CGRectGetHeight(rect) + 2 * offset;
    
}

Теперь возвращаемся во ViewController и в делегате с помощью return вызвать метод класса cusomCell и получить от него информацию о высоте вашей ячейки.

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    return [customCell heightForText: self.textStringHabr];
    
}

Проверяем.



Всё работает!

Теперь ячейка сама высчитывает нужную вам высоту. Главное не забыть, что мы создали кастомную ячейку и указать это в двух обязательных табличных методах.

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString* identifier = @"cell";
    
    customCell* cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    
    if (!cell) {
        cell = [[customCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
    }
    
    cell.testTextLabel.text = self.textStringHabr;
    
    return cell;
}


Для тех, кто пишет на Swift, всё гораздо проще, Apple избавила нас от этого написания кода и там все делается с помощью всего лишь двух строчек кода.

self.tableView.rowHeight = UITableViewAutomaticDimension
        
self.tableView.estimatedRowHeight = 44.0

Информация взята из уроков Алексея Скутаренко.

Спасибо за внимание, надеюсь, что смог помочь хоть чем то.
Теги:
Хабы:
Всего голосов 14: ↑7 и ↓70
Комментарии19

Публикации

Истории

Работа

iOS разработчик
27 вакансий
Swift разработчик
37 вакансий

Ближайшие события

19 августа – 20 октября
RuCode.Финал. Чемпионат по алгоритмическому программированию и ИИ
МоскваНижний НовгородЕкатеринбургСтавропольНовосибрискКалининградПермьВладивостокЧитаКраснорскТомскИжевскПетрозаводскКазаньКурскТюменьВолгоградУфаМурманскБишкекСочиУльяновскСаратовИркутскДолгопрудныйОнлайн
24 – 25 октября
One Day Offer для AQA Engineer и Developers
Онлайн
25 октября
Конференция по росту продуктов EGC’24
МоскваОнлайн
26 октября
ProIT Network Fest
Санкт-Петербург
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань