...

вторник, 1 июля 2014 г.

Нескучные UITableViews


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

Внимание! Под катом — тяжелые GIFки.



Первым делом — объявим несколько новых свойств в .h-файле нашего контроллера:



@property (strong, nonatomic) NSNumber* cellZoomXScaleFactor;
@property (strong, nonatomic) NSNumber* cellZoomYScaleFactor;
@property (strong, nonatomic) NSNumber* cellZoomXOffset;
@property (strong, nonatomic) NSNumber* cellZoomYOffset;
@property (strong, nonatomic) NSNumber* cellZoomInitialAlpha;
@property (strong, nonatomic) NSNumber* cellZoomAnimationDuration;




Забегая немного вперед, расскажу, за что каждое из них будет отвечать:


  • cellZoomXScaleFactor — масштабирование ячейки в горизонтальной плоскости,

  • cellZoomYScaleFactor — масштабирование ячейки в вертикальной плоскости,

  • cellZoomXOffset — сдвиг ячейки в горизонтальной плоскости,

  • cellZoomYOffset — сдвиг ячейки в вертикальной плоскости,

  • cellZoomInitialAlpha — прозрачность ячейки,

  • cellZoomAnimationDuration — длительность анимации.




Теперь займемся подготовкой почвы для экспериментов со значениями введенных свойств. Сначала, используя #define, создадим набор макросов:

#define CELL_ZOOM_X_SCALE_FACTOR 0.5
#define CELL_ZOOM_Y_SCALE_FACTOR 0.5
#define CELL_ZOOM_X_OFFSET 0
#define CELL_ZOOM_Y_OFFSET 0
#define CELL_ZOOM_INITIAL_ALPHA 0.7
#define CELL_ZOOM_ANIMATION_DURATION 0.6




В методе -viewDidLoad свяжем макросы с объявленными свойствами:

_cellZoomXScaleFactor = [NSNumber numberWithFloat:CELL_ZOOM_X_SCALE_FACTOR];
_cellZoomYScaleFactor = [NSNumber numberWithFloat:CELL_ZOOM_Y_SCALE_FACTOR];
_cellZoomXOffset = [NSNumber numberWithFloat:CELL_ZOOM_X_OFFSET];
_cellZoomYOffset = [NSNumber numberWithFloat:CELL_ZOOM_Y_OFFSET];
_cellZoomInitialAlpha = [NSNumber numberWithFloat:CELL_ZOOM_INITIAL_ALPHA];
_cellZoomAnimationDuration = [NSNumber numberWithFloat:CELL_ZOOM_ANIMATION_DURATION];




И последний штрих перед тем, как перейти непосредственно к программированию поведения ячейки — добавим переменные для хранения номера последних отображенных ячейки и секции таблицы:

@implementation HomeViewController {
int currentMaxDisplayedCell;
int currentMaxDisplayedSection;
}




И, наконец-то, самое интересное. Поведение ячейки будем задавать в методе -willDisplayCell:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section >= currentMaxDisplayedSection && indexPath.row > currentMaxDisplayedCell) {
cell.contentView.alpha = self.cellZoomInitialAlpha.floatValue;

CGAffineTransform transformScale = CGAffineTransformMakeScale(self.cellZoomXScaleFactor.floatValue, self.cellZoomYScaleFactor.floatValue);
CGAffineTransform transformTranslate = CGAffineTransformMakeTranslation(self.cellZoomXOffset.floatValue, self.cellZoomYOffset.floatValue);

cell.contentView.transform = CGAffineTransformConcat(transformScale, transformTranslate);

[tableView bringSubviewToFront:cell.contentView];
[UIView animateWithDuration:self.cellZoomAnimationDuration.floatValue
delay:0
options:UIViewAnimationOptionAllowUserInteraction
animations:^{
cell.contentView.alpha = 1;
cell.contentView.transform = CGAffineTransformIdentity;
} completion:nil];

currentMaxDisplayedCell = indexPath.row;
currentMaxDisplayedSection = indexPath.section;
}
}


Разберемся в том, что здесь происходит:

1. Анимируются только ранее не показанные ячейки — здесь и приходят на помощь объявленные ранее переменные currentMaxDisplayedSection и currentMaxDisplayedCell.

2. Задаем прозрачность ячейки, используя свойство cellZoomInitialAlpha. Если оно изначально будет равным 1, эффект смены прозрачности заметен не будет.

3. Задаем значение свойства transform нашей ячейки с использованием функции CGAffineTransformConcat().

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

5. Задаем переменным currentMaxDisplayedSection и currentMaxDisplayedCell значения текущего ряда и секции.


А теперь можно приступать к экспериментам с разными значениями введенных свойств. Для удобства наборы значений буду описывать по следующему шаблону: (CELL_ZOOM_X_SCALE_FACTOR, CELL_ZOOM_Y_SCALE_FACTOR, CELL_ZOOM_X_OFFSET, CELL_ZOOM_Y_OFFSET, CELL_ZOOM_INITIAL_ALPHA, CELL_ZOOM_ANIMATION_DURATION).


Начнем со стартового набора, который мы уже успели задать (0.5, 0.5, 0, 0, 0.7, 0.6):


Попробуем поиграть с прозрачностью (1, 1, 0, 0, 0.0, 0.7):


Создадим эффект выплывания из-за края экрана (1, 1, -50, 0, 1.0, 0.4):


Реализуем эффект переворачивающихся карточек (1, 0.01, 0, 0, 1.0, 0.4):


И напоследок немного кошачьего безумия (0.01, 0.01, 100, 100, 1.0, 0.4):


Не обязательно останавливаться на приведенных примерах — меняя эти значения, можно добиться большого количества разных эффектов. Не забывайте о том, что к каждой яейке эффект применяется лишь однажды — при ее первом показе. При желании, это можно изменить, в нужный момент изменяя значения переменных currentMaxDisplayedSection и currentMaxDisplayedCell.


This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий