Diese Präsentation wurde erfolgreich gemeldet.
Die SlideShare-Präsentation wird heruntergeladen. ×

Rambler.iOS #7: Построение сложного табличного интерфейса

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Андрей Резанов
Построение сложного
табличного интерфейса

YouTube-Videos werden auf SlideShare nicht mehr unterstützt.

Original auf YouTube ansehen

7.8
Название
Тип
Тег №2Тег №1
Станция метро
Адерс места
Название места
Лучшие Недавние
Lorem ipsum dolor sit amet, consect...

Hier ansehen

1 von 29 Anzeige

Rambler.iOS #7: Построение сложного табличного интерфейса

Herunterladen, um offline zu lesen

Rambler.iOS #7: Построение сложного табличного интерфейса (Резанов Андрей).

Rambler.iOS - митапы iOS-разработчиков, организуемые компанией RAMBLER&Co.

Rambler.iOS #7: Построение сложного табличного интерфейса (Резанов Андрей).

Rambler.iOS - митапы iOS-разработчиков, организуемые компанией RAMBLER&Co.

Anzeige
Anzeige

Weitere Verwandte Inhalte

Andere mochten auch (20)

Ähnlich wie Rambler.iOS #7: Построение сложного табличного интерфейса (20)

Anzeige

Weitere von RAMBLER&Co (15)

Aktuellste (20)

Anzeige

Rambler.iOS #7: Построение сложного табличного интерфейса

  1. 1. Андрей Резанов Построение сложного табличного интерфейса
  2. 2. 7.8 Название Тип Тег №2Тег №1 Станция метро Адерс места Название места Лучшие Недавние Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco…... далее Имя пользователя Дата Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco… далее Заголовок блока Важная информация Дополнительная информация Режим работы Расписание работы Режим работы:
  3. 3. 7.8 Название Тип Станция метро Адерс места Название места Лучшие Недавние Заголовок блока Важная информация Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco… далее Дополнительная информация Дополнительная информация Дополнительная информация Тег №2Тег №1 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco…... далее Имя пользователя Дата Режим работы Расписание работы Режим работы:
  4. 4. 7.8 Название Тип Лучшие Недавние Заголовок блока Важная информация Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco…... далее Имя пользователя Дата Режим работы Расписание работы Режим работы: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco… далее Станция метро Адерс места Название места Дополнительная информация Дополнительная информация Дополнительная информация Дополнительная информация Тег №2Тег №1
  5. 5. Построение сложного табличного интерфейса Постановка задачи – Афиша iOS • Уметь строить 30+ различных ячеек • Располагать ячейки в различном порядке в зависимости от 10 + конфигураций экрана • В будущем необходимо добавлять новый ячейки / конфигурации экрана
  6. 6. Построение сложного табличного интерфейса Решение в лоб! Why not? - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { Creation *creation = [self itemAtIndexPath:indexPath]; NSString *cellIdentifier = [self cellIdentifierForObject:creation atIndexPath:indexPath]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; if ([cellIdentifier isEqualToString:RCATitleTableViewCell]) { TitleTableViewCell *titleCell = (TitleTableViewCell *)cell; [titleCell fillWithCreation:creation]; } else if ([cellIdentifier isEqualToString:RCARatingTableViewCell]) { RatingTableViewCell *ratingCell = (RatingTableViewCell *)cell; [ratingCell fillWithRating:creation.rating]; } ... return cell; }
  7. 7. Построение сложного табличного интерфейса • Неконтролируемый рост полотна кода в cellForRow • Сложно добавлять новые ячейки, модифицировать порядок ячеек • Нарушение принципа единственной ответственности (SOLID) Решение в лоб - Проблемы
  8. 8. Построение сложного табличного интерфейса Решение в лоб! Why not? Декомпозиция
  9. 9. Построение сложного табличного интерфейса Шаг 1. Внедряем View-модели 🐣 Модель представления - абстракция представления, которая содержит свойства Модели.
  10. 10. Построение сложного табличного интерфейса Шаг 1. Внедряем View-модели 🐣
  11. 11. Построение сложного табличного интерфейса Класс TableViewModel - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { . . . id viewModel = [self viewModelAtIndexPath:indexPath]; . . . } 1. Получаем view-модель по indexPath
  12. 12. Построение сложного табличного интерфейса Класс TableViewModel - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { . . . Class cellClass = [self cellClassFromViewModel:viewModel]; . . . } 2. Получаем класс ячейки у view-модели
  13. 13. Построение сложного табличного интерфейса Класс TableViewModel - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { . . . cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(cellClass)]; . . . } 3. Реюзаем / создаем ячейку
  14. 14. Построение сложного табличного интерфейса Класс TableViewModel - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { . . . [cell updateCellWithViewModel:viewModel]; . . . } 4. Заполняем ячейку данными из view-модели
  15. 15. Построение сложного табличного интерфейса Класс TableViewActions - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { . . . id viewModel = [model viewModelAtIndexPath:indexPath]; . . . } 1. Получаем view-модель по indexPath
  16. 16. Построение сложного табличного интерфейса Класс TableViewActions - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { . . . NSString *cellHeightID = [self cellHeightIDWithTableView:tableView viewModel:viewModel]; NSNumber *cachedHeight = [self.cellHeightCache objectForKey:cellHeightID]; if (cachedHeight) { return [cachedHeight floatValue]; } . . . } 2. Если есть закэшированное значение высоты ячейки, то возвращаем его
  17. 17. Построение сложного табличного интерфейса Класс TableViewActions - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { . . . Class cellClass = [viewModel cellClass]; . . . } 3. Получаем класс ячейки у view-модели
  18. 18. Построение сложного табличного интерфейса Класс TableViewActions - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { . . . CGFloat height; if ([cellClass respondsToSelector:@selector(heightForViewModel:atIndexPath:tableView:)]) { height = [cellClass heightForViewModel:viewModel atIndexPath:indexPath tableView:tableView]; } else { . . . } 4. Если ячейки умеет сама рассчитывать высоту, то возвращаем ее
  19. 19. Построение сложного табличного интерфейса Класс TableViewActions - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { . . . UITableViewCell<Cell> *cell = [self tableViewCellWithViewModel:tableView tableView:tableView]; [cell updateCellWithViewModel:viewModel]; height = [self tableView:tableView heightForTableViewCell:cell]; . . . } 5. Считаем высоту через статичный прототип ячейки
  20. 20. Построение сложного табличного интерфейса Класс TableViewActions - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { . . . [cellHeightCache setObject:@(height) forKey:cellHeightID]; . . . } 6. Кэшируем значение высоты
  21. 21. Построение сложного табличного интерфейса Чего-то не хватает?
  22. 22. Построение сложного табличного интерфейса Метод построения view-моделей 2000 + строк кода
  23. 23. Построение сложного табличного интерфейса Шаблон проектирования Строитель (англ. Builder) Порождающий шаблон проектирования предоставляет способ создания составного объекта.
  24. 24. Построение сложного табличного интерфейса Шаг 2. Внедряем Билдер
  25. 25. Построение сложного табличного интерфейса Диаграмма последовательности (англ. Sequence diagram)
  26. 26. Построение сложного табличного интерфейса Выводы 1. Внедрение view-моделей дает: слабую связность, дополнительный слой между моделью и view 2. Никакой логики во view 3. Чистый и универсальный cellForRow, heightForRow 4. Внедрение билдера дает: разделение логики построения блоков ячеек от логики сбора их вместе 5. Легкая возможность расширения данной схемы. Как появление новых блоков/ячеек, так и появление новых экранов, например - для квестов! 6. Модульность кода
  27. 27. Построение сложного табличного интерфейса Литература и ссылки The "Gang of Four” - Design Patterns: Elements of Reusable Object-Oriented Software Erick Buck, Donald Yachtman - Cocoa Design Patterns OBJC.IO Issue 13 - Architecture OODesign.com - Builder pattern NimbusKit - Table View Models
  28. 28. Построение сложного табличного интерфейса Спасибо!

×