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

Нарядная табличка (Custom Table)

На этом примере я покажу вам как адаптировать стандартную таблицу под любой интерфейс. Вот, что у нас должно получится в результате.

 

 

Чтобы не создавать новый проект я предлагаю использовать код с примера Самая простая таблица (UITableView). Того минимального набора функционала, который содержится в этом коде нам будет достаточно. Для преображения таблицы я предлагаю использовать уже подобранный мною набор картинок, который можно скачать здесь. Если предложенные картинки не подходят под ваш интерфейс — можете заменить их своими. Добавьте картинки в проект (в папку Supporting Files).

 

Для начала изменим метод viewDidLoad, который находится в реализации класса RootViewController.

 

<code data-result="[object Object]">- (void)viewDidLoad
{
    [super viewDidLoad];
    self.navigationController.navigationBar.hidden = YES;

    self.students = [NSArray arrayWithObjects:@"Tom", @"Bill", @"Tom", @"Joe", @"Tom", nil];

    self.tableView.rowHeight = 100;
    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"gradientBackground.png"]];
}</code>

 

В первую очередь мы прячем навигейшин бар (он не подходит под стиль таблицы). Затем создаем массив элементов, который будет источником данных для таблицы и задаем некоторые параметры для всей таблицы (всех ее ячеек):

 

  • мы убираем разделители ячеек (они у нас будут свои, красивые)
  • задаем высоту каждой ячейки (согласно высоте картинок, которые будут помещены в ячейки)
  • устанавливаем фоновый рисунок для таблицы

 

Для добавления красивого заголовка я использовал следующий код, который так же добавил в метод viewDidLoad:

 

<code data-result="[object Object]">UIView *containerView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 60)] autorelease];
UILabel *headerLabel = [[[UILabel alloc] initWithFrame:CGRectMake(10, 20, 300, 40)] autorelease];
headerLabel.text = @"imaladec.com";
headerLabel.textColor = [UIColor whiteColor];
headerLabel.shadowColor = [UIColor blackColor];
headerLabel.shadowOffset = CGSizeMake(0, 1);
headerLabel.font = [UIFont boldSystemFontOfSize:22];
headerLabel.backgroundColor = [UIColor clearColor];
[containerView addSubview:headerLabel];
self.tableView.tableHeaderView = containerView;</code>

 

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

 

Теперь наша таблица имеет совершенно другой вид:

 

 

Но это еще не конец, давайте перейдем к методу cellForRowAtIndexPath:

 

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

    UILabel *topLabel;
    UILabel *bottomLabel;

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

        //Помещение картинки indicator.png в accessoryView
        UIImage *indicatorImage = [UIImage imageNamed:@"indicator.png"];
        cell.accessoryView = [[[UIImageView alloc] initWithImage:indicatorImage] autorelease];

        //Создание константы для хранения высоты надписей
        const CGFloat LABEL_HEIGHT = 20;
        //Получение картинки imageA.png (она нужна будет для получения размеров этой картинки)
        UIImage *image = [UIImage imageNamed:@"imageA.png"];

        //Инициализация верхней надписи
        CGRect topLabelFrame = CGRectMake(image.size.width + 2.0 * cell.indentationWidth, 
                                          0.5 * (tableView.rowHeight - 2 * LABEL_HEIGHT), 
                                          tableView.bounds.size.width - image.size.width - 
                                          4.0 * cell.indentationWidth - indicatorImage.size.width, 
                                          LABEL_HEIGHT);
        topLabel = [[[UILabel alloc] initWithFrame:topLabelFrame] autorelease];
        [cell.contentView addSubview:topLabel];

        //установка значений для верхней надписи
        topLabel.tag = 1;
        topLabel.backgroundColor = [UIColor clearColor];
        topLabel.textColor = [UIColor colorWithRed:0.25 green:0.0 blue:0.0 alpha:1.0];
        topLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
        topLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize]];

        //Инициализация нижней надписи
        CGRect bottomLabelFrame = CGRectMake(image.size.width + 2.0 * cell.indentationWidth,
                                             0.5 * (tableView.rowHeight - 2 * LABEL_HEIGHT) + LABEL_HEIGHT, 
                                             tableView.bounds.size.width - image.size.width - 
                                             4.0 * cell.indentationWidth - indicatorImage.size.width, 
                                             LABEL_HEIGHT);
        bottomLabel = [[[UILabel alloc] initWithFrame:bottomLabelFrame] autorelease];
        [cell.contentView addSubview:bottomLabel];

        //установка значений для нижней надписи
        bottomLabel.tag = 2;
        bottomLabel.backgroundColor = [UIColor clearColor];
        bottomLabel.textColor = [UIColor colorWithRed:0.25 green:0.0 blue:0.0 alpha:1.0];
        bottomLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
        bottomLabel.font = [UIFont systemFontOfSize:[UIFont labelFontSize] - 2];

        //инициализация фонов
        cell.backgroundView = [[UIImageView new] autorelease];
        cell.selectedBackgroundView = [[UIImageView new] autorelease];

    } else {
        //получение надписей по тэгу
        topLabel = (UILabel *)[cell viewWithTag:1];
        bottomLabel = (UILabel *)[cell viewWithTag:2];
    }

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

    return cell;
}</code>

 

Этот код можно разложить на несколько этапов:

  • объявление двух переменных типа UILabel для вывода текста в ячейки;
  • после создания ячейки помещаем на место accessoryView картинку indicator.png;
  • создание константы, в которой храним высоту надписей;
  • инициализация картинки imageA.png для получения ее размеров (они пригодятся для установки высоты надписей);
  • инициализаци я добавление на ячейку верхней надписи
  • установка значений для верхней надписи
  • инициализаци я добавление на ячейку нижней надписи
  • установка значений для нижней надписи
  • инициализация фона
  • инициализация фона выделенной ячейки
  • если ячейка уже существует — получаем надписи по тэгу установленному в момент создания ячейки

Теперь заполним созданные переменные. Для этого замените строку

 

<code data-result="[object Object]">cell.textLabel.text = [students objectAtIndex:indexPath.row];</code>

 

группой строк:

 

<code data-result="[object Object]">//установка значений для надписей
topLabel.text = [students objectAtIndex:indexPath.row];
bottomLabel.text = @"Student";

//создание картинок которые будем помещать в ячейки
UIImage *rowBackground;
UIImage *selectionBackground;
NSInteger sectionRows = [tableView numberOfRowsInSection:[indexPath section]];
NSInteger row = [indexPath row];
if (row == 0 &amp;&amp; row == sectionRows - 1)
{
    //Если ячейка одна в группе - устанавилваем ей картинку со всеми закругленными углами
    rowBackground = [UIImage imageNamed:@"topAndBottomRow.png"];
    selectionBackground = [UIImage imageNamed:@"topAndBottomRowSelected.png"];
}
else if (row == 0)
{
    //для первой ячейки в группе - устанавливаем картинку с верхними закругленными углами
    rowBackground = [UIImage imageNamed:@"topRow.png"];
    selectionBackground = [UIImage imageNamed:@"topRowSelected.png"];
}
else if (row == sectionRows - 1)
{
    //всем ячейкам, которые в середине группы устанавливаем картинки без закругленных углов
    rowBackground = [UIImage imageNamed:@"bottomRow.png"];
    selectionBackground = [UIImage imageNamed:@"bottomRowSelected.png"];
}
else
{
    //последней ячейке устанавливаем картинку с закругленными нижними углами
    rowBackground = [UIImage imageNamed:@"middleRow.png"];
    selectionBackground = [UIImage imageNamed:@"middleRowSelected.png"];
}

//установка картинок
((UIImageView *)cell.backgroundView).image = rowBackground;
((UIImageView *)cell.selectedBackgroundView).image = selectionBackground;

//установка ячейкам допольнительных картинок (для красоты)
if ((row % 3) == 0)
{
    cell.imageView.image = [UIImage imageNamed:@"imageA.png"];
}
else if ((row % 3) == 1)
{
    cell.imageView.image = [UIImage imageNamed:@"imageB.png"];
}
else
{
    cell.imageView.image = [UIImage imageNamed:@"imageC.png"];
}</code>

 

Как видно с кода (я оставил комментарии) сначала мы устанавливаем значения для только что созданных надписей. Затем инициализируем картинки, которые будем помещать в ячейки, в зависимости от положения ячейки устанавливается своя картинка. После инициализации картинок мы устанавливаем их свойствам ячейки (backgroundView и selectedBackgroundView). На последок (для большего украшения) устанавливаем ячейкам дополнительные картинки (мы так уже делали в примере Более подробно о ячейках).

 

Относительно небольшая часть кода и несколько картинок значительно могут преобразить внешний вид всей таблицы. В следующем примере я расскажу как создавать собственные ячейки, в которые мы поместим больше чем два поля надписи. А исходный код этого проекта можно скачать здесь.