Задание 4. CS193P Winter 2017. Smashtag Mentions (клиент Twitter). Решение — дополнительный пункт 6. UICollectionView с расположением ячеек типа WaterFall и переключение между Layouts.

Класс UICollectionView отличается UITableView наличием свойства UICollectionViewLayout, которое отвечает за расположение (layout) ячеек в двухмерным пространстве, не заботясь о содержимом этих ячеек. По умолчанию работает расположение (layout)  UICollectionViewFlowLayout, которое действует наподобие размещения текста по строкам слева направо с переносом на другую строку. Именно этот layout мы использовали при выполнении дополнительного пункта 6 Задания 4. Но есть очень привлекательное расположение ячеек, которое организует их по столбцам таким образом, чтобы они как можно плотнее заполняли все пространство. Это так называемый стиль Pinterest или еще его называют «анти-Тэтрис» или Waterfall (водопад). Выше на рисунке цифрами показан порядок заполнения ячеек в случае обычного Flow и Waterfall расположения ячеек, и мы видим, что последний уплотняет расположение ячеек, давая снизу появиться новым ячейкам.
Алгоритм расположение очень прост: каждая следующая ячейка располагается в столбце, наименее занятом по вертикали,  c соответствующим Aspect ratio.  Класс CHTCollectionViewWaterfallLayout, реализующий этот алгоритм расположения ячеек в Collection View представлен в Github. Давайте попробуем использовать его в решении Задания 4.

Код находится на Github.


Для этого разместим файл CHTCollectionViewWaterfallLayout.swift в нашем проекте и сделаем небольшую настройку в нашем классе ImageCollectionViewController в методе «жизненного» цикла viewDidLoad:

При настройке layout  Waterfall самым главным параметром является количество столбцов columnCount и реализация обязательного метода протокола CHTCollectionViewDelegateWaterfallLayout для расчета размеров ячейки:

На самом деле параметр columnCount можно не задавать, так как в классе CHTCollectionViewWaterfallLayout  он выставлен по умолчанию равным 2. Подтверждение протокола CHTCollectionViewDelegateWaterfallLayout классом ImageCollectionViewController и реализация его обязательного метода оформлены виде расширения extension, который мы разместили в том же файле:

Нам пришлось изменить доступ к массиву images и структуре Constants на fileprivate:

И можно запускать приложение:


Это результат работы с параметрами настройки, заданными по умолчанию:

  • количество столбцов — 2
  • расстояние между ячейками — 10
  • расстояние между строками — 10
  • зазоры для секции — 0

Переходим в ландшафтный режим, и число столбцов автоматически меняется на 3.
Мы захотим менять некоторые параметры, поэтому нужно предусмотреть некоторые константы, которые вы можете задавать, чтобы изменить расположение ячеек

Screen Shot 2016-07-22 at 4.33.32 PM

С нашими настройками сократилось расстояние между ячейками и строками до 2 и количество столбцов columnCount  равное 3 сохраняется как в портретном , так и в ландшафтном режимах:

Остается решить вопрос с масштабирование с помощью жеста pinch. Надо сказать, что изменение размера ячейки с помощью жеста pinch, которое мы применяли для layout CollectionViewFlowLayout не действует на CHTCollectionViewWaterfallLayout — она упорно «держит» свои 3 столбца. Поэтому в этом случае будем воздействовать с помощью переменной scale на количество столбцов:

В силу дискретности количества столбцов columnCount  размещение масштаба будет происходить не плавно, а скачками.
Это все. Код  находится на Githib.

Теперь у нам два варианта расположения ячеек:

  • FlowLayout — стандартный
  • WaterfallLayout — в стиле Pinterest

Давайте организуем переключение между этими двумя расположениями ячеек.
Введем для них две private переменные

Screen Shot 2015-07-14 at 5.45.22 PM

Добавим дополнительную кнопку для выполнения этого переключения как правую кнопку навигационной панели:

Само переключение выполняется в функции, указанной при инициализации кнопки:

При переключении ячейки Collection View будут анимировать. Посмотрим результат.

Screen Shot 2016-07-22 at 4.46.32 PM

Screen Shot 2016-07-22 at 4.56.32 PM

Код находится на Github.