ПРОГРАММИРОВАНИЕ ПОД IPHONE, IPAD OBJECTIVE-C часть 2

Подсчет высоты ячейки

 

Я считаю, что нет смысла описыавть о чем пойдет речь в этом примере. Все и так понятно с картинки. Поэтому предлагаю сразу приступить к делу. Для начала создадим проект с шаблона (Navigation-Based Application). Я выбрал именно этот шаблон потому, что в нем уже содержиться таблица. Свой проект я назвал CalculateHighetCell. Хочу предупредить сразу, что новости мы не будем брать с сайта. Это не пример парсинга или скачивания rss с сервера. Более того, код этого проекта очень похож на пример Самая простая таблица (UITableView). В первую очередь заставим нашу таблицу просто выводить данные, как это показано на рисунке слева. Для этого внесем некоторые изменения в класс RootViewController.

 

RootViewController.h

<code data-result="[object Object]">#import &lt;UIKit/UIKit.h&gt;

@interface RootViewController : UITableViewController {
    NSArray *news;   
}

@property (nonatomic, retain) NSArray *news;

@end</code>

 

В интерфейсе мы люъявили массив, в котором будут храниться новости.

 

RootViewController.m

 

<code data-result="[object Object]">#import "RootViewController.h"

@implementation RootViewController

@synthesize news;

- (void)dealloc
{
    self.news = nil;
    [super dealloc];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.news = [NSArray arrayWithObjects:
                     @"Подсчет высоты ячейки",
                     @"Как обновить свой iPhone 4 до 4S", 
                     @"Отключаем функцию восстановления в `Просмотре` в Mac OS X Lion", 
                     @"За первые 24 часа Apple получила более миллиона предзаказов на iPhone 4S", 
                     @"Fruit Ninja: Puss in Boots появится в App Store уже в этом месяце",
                     @"Sony Pictures хочет снять фильм про Стива Джобса", nil];
}

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return news.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.text = [news objectAtIndex:indexPath.row];

    return cell;
}

@end</code>

 

Как я уже говорил, пока что, код этого примера мало чем отличается от нашей первой таблици. Теперь изменим свойства UILabel, который мы заполняем. Делать это мы будем в момент создания ячейки, а значит в методе cellForRowAtIndexPath:

 

<code data-result="[object Object]">- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                       reuseIdentifier:CellIdentifier] autorelease];

        cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
        cell.textLabel.numberOfLines = 0;
    }

    cell.textLabel.text = [news objectAtIndex:indexPath.row];

    return cell;
}</code>

 

Все изменение сводится к добавлению двух стрк. В первой строке мы устанавливаем метод переноса текста, а во второй — количество строк (0 — это бесконечно).

 

Но для полноценной работы нашей таблицы необходим еще одим метод, в котором мы будем подсчитывать высоту каждой ячейки. Это метод heightForRowAtIndexPath:

 

<code data-result="[object Object]">- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{    
    NSString *cellText = [news objectAtIndex:indexPath.row];
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica-Bold" size:20.0f];
    CGSize constraintSize = CGSizeMake(320.0f, MAXFLOAT);

    CGSize labelSize = [cellText sizeWithFont:cellFont 
                            constrainedToSize:constraintSize 
                                lineBreakMode:UILineBreakModeWordWrap];

    return labelSize.height + 20.0f;
}</code>

 

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

 

  • Текст, высоту которого мы будем подсчитывать (cellText)
  • Шрифт, который применен к этому тексту (cellFont)
  • Ширина текстового поля (constraintSize)

 

Именно эти данные я и получаю в приведеном выше коде. Шрифт текстового поля я узнал с помощью отладчика. Для установки значения переменной constraintSize я использовал метод CGSizeMake, в который передал ширину ячейки, а в качестве высоты установил максимальное значение CGFloat. После того как все «ингридиенты» получены я использовал метод sizeWithFontкласса NSString (точнее это не его метод, а метод одной из его категорий, но для нас это не важно). Важно то, что этот метод возвращает высоту текстового поля. К полученой высоте я добавил еще 20 пикселей чтобы ячейки таблици визуально не сливались и возвратил полученное значение.

 

Исходный код этого примера можно скачать здесь.