Текст Домашнего задания на английском языке доступен на iTunes в пункте “Developing iOS 8 app: Programming: Project 4″. Текст Домашнего задания на русском языке доступен на Для выполнения этого Задания необходимо освоение Лекции 9, Лекции 10, и Лекции 11.
В этом посте подробно описывается выполнение обязательных пунктов 1-4.
Код для Swift 1.2 находится на Github. Код для Swift 2.0 находится на Github.
Пункт 1 обязательный
Усовершенствуйте приложение Smashtag, полученное на лекции, в части выделения (разными цветами каждого) hashtags, urls и user screen names, упомянутых в тексте твита (они известны как “mentions” — меншены). Заметьте, что эти mentions уже обнаружены для вас в каждом твите и представлены как [IndexedKeyword]s в классе Tweet в поставляемом коде Twitter.
Класс Tweet.swift обеспечивает нас всем необходимым – массивами структур [IndexedKeyword] для каждой категории меншенов (mentions) в конкретном твите.
Нам остается создать палитру цветов для раскраски меншенов, объявить это свойство как public API для прототипа ячейки TweetTableViewCell
а затем раскрасить меншены в специальном методе формирования текста твита
с помощью класса NSMutableAttributedString, предварительно создав ему расширение для установки заданного цвета текста для заданного диапазона
Обновление текста происходит в хорошо знакомом нам методе updateUI()
. . . . . . . . . . . . .
Таким образом, мы не вы “не разрушили” preferred body фонт, используемый для показа твита.
Запускаем приложение и получаем требуемый результат.
Пункты 2, 3, 4 обязательные
- Когда пользователь кликает на твите, “переезжайте” (segue) на новый UITableViewController, у которого 4 секции, показывающие “mentions” в твите: Images, URLs, Hashtags и Users. Первая секция показывает (одно на строку) любые изображения, прикрепленные к твиту (найдены в переменной media в классе Tweet). Последние 3 секции показывают элементы, описанные в Обязательном пункте №1 (опять, по одному на строку).
- Каждая секция в таблице “mentions” должна иметь соответствующие заголовки.
- Если в секции нет никаких элементов, то заголовок не должен быть виден для этой секции.
Добавляем из палитры объектов дополнительный Table View Controller на storyboard. В этой таблице нам будут нужны два прототипа ячеек таблицы: один для того, чтобы поместить туда строку: URLs, Hashtags и Users, а другой прототип — для размещения изображений Images.
Один прототип — он имеет идентификатор Keyword Cell — это обычная табличная ячейка UITableViewCell, имеющая стиль Basic , который позволяет вывести на экран только заголовок Title, то есть разместить строку.
Другой прототип — он имеет идентификатор Image Cell — это ячейка, настраиваемая пользователем, поэтому задаем ей стиль Custom. Для нее мы создадим специальный класс ImageTableViewCell, который позволит загрузить в ячейку изображение. Изображение Image View нужно перетянуть из палитры объектов на storyboard в этот custom прототип ячейки и сделать все необходимые настройки для механизма Autolayout.
Не забудьте создать специальный класс ImageTableViewCell для нашей ячейки и установить его в Инспекторе Идентичности (Identity Inspector) для прототипа Image Cell.
Но вернемся к нашей таблице и создадим для нее специальный класс MentionsTableViewController, который является subclass UITableViewController и не забудем указать его в Инспекторе Идентичности (Identity Inspector) для нашей таблице на storyboard.
Давайте подумаем, что является для нашего класс MentionsTableViewController public API. Согласно заданию эта таблица должна отображать меншены для определенного твита, следовательно сам твит и является public API класса MentionsTableViewController. То есть своего рода Моделью в терминологии паттерна проектирования MVC.
Имея твит tweet, мы должны извлечь все меншены и отобразить их в таблице. Для отображения данных в таблице в подсказке № 7 Задания 4 нам предлагают создать внутреннюю структуру данных, которая бы собирала данные по секциям (учитывая их похожесть и различия) и очень просто работала бы с UITableViewDataSource таблицы Table View.
Давайте подробно остановимся на построением этой структуры данных, потому что простота и ясность решения нашей задачи очень сильно будет зависеть от этой структуры.
На верхнем уровне будет массив секций mentionTypes: [MentionType], представленных структурой MentionType, в которой задается тип секции type, который одновременно является и названием секции, и массив меншенов этого типа mentions : [Mention].
Каждый меншен представлен перечислением enum Mention, который включает в себя два варианта:
- просто ключевое слово Keyword (String) c ассоциированным значением String в виде строки,
- изображение Image (NSURL, Double) c ассоциированными значениями виде NSURL (где взять изображение) и Double ( aspect ratio или соотношение сторон).
Первый вариант подходит для меншенов hashtags, urls и user screen names, а второй — для images. Имея такую структуру очень просто реализовать методы делегата UITableViewDataSource для таблицы.
Особого внимания заслуживает последний метод cellForRowAtIndexPath, в котором используются два различных прототипа ячеек: обычный UITableViewCell для меншенов, представленных ключевым словом, и ImageTableViewCell для меншенов, представленных ключевым изображением.
Чтобы покончить с методами делегата Table View, примем к рассмотрению подсказки № 17 — 19 Задания 4.
17. Высота строки в вашем новом Сontroller не нуждается в “оценке” как высота строки в “списке твитов”, потому что у вас очень мало строк и производительность не играет решающего значения. Следовательно, вам захочется реализовать метод heightForRowAtIndexPath делегата UITableViewDelegate.
18. Для строк, содержащих изображение ( image), вам придется рассчитать подходящую высоту. Для других строк в вашей таблице вы можете позволить рассчитаться высоте строки автоматически (используя Autolayout) путем возврата UITableViewAutomaticDimension из метода heightForRowAtIndexPath.
19. Вы можете рассчитать соотношение сторон (aspect ratio) изображения (image) в твите, не прибегая к реальной выборки image из своего url. Смотри класс MediaItem в дополнительных Twitter классах.
Следуя этим рекомендациях получаем код для еще двух методов делегата Table View.
Теперь осталась самая главная и интересная часть — загрузить нашу таблицу данными, а ведь у нас кроме твита tweet ничего нет в public API, поэтому следующая наша задача — преобразовать tweet во внутреннюю структуру mentionTypes: [MentionType], и сделать мы это должны как только кто-то извне установит нам значение переменной tweet.
Надо сказать, что этот код с точки зрения паттерна конструирования MVC выполняет типичную для Controller задачу — преобразование данных Модели в данные, требуемые View.
Осталось подсоединить вновь созданный Mentions Table View Controller к списку твитов Tweets Table View Controller, и мы сделаем это с помощью push segue от ячейки в таблице Tweets Table View Controller к таблице меншенов.
Не забывайте указать идентификатор segue, он нам пригодится в коде. Мы задали идентификатор как Show Mentions и поместим его в специальную структуру в классе TweetsTableViewController.
Еще нам нужно написать в этом же классе метод prepareForSegue:
Именно в выделенной выше строке происходит использование public API класса MentionsTableViewController и именно она позволит запустит механизм загрузки таблицы меншенов.
Осталась еще одна и последняя маленькая деталь — это пользовательский класс ImageTableViewCell, обслуживающий прототип ячейки Image Cell, отображающей изображения. Для этого класса public API будет URL местонахождения изображения в сети — imageURL: NSURL. Нам нужно закачать оттуда данные и отобразить в ячейке. Причем выполнить все это мы должны, не блокируя main queue. Это задача нам уже знакома по приложению Cassini, которое рассматривалось на Лекции 9, поэтому я не буду останавливаться подробно на описании кода.
Запускаем приложение и смотрим вариант с изображением.
Смотрим вариант без изображения — эта секция отсутствует.
Проверим выполнение пункта № 20 в подсказках
20. Замечательной возможностью вашего приложения является (должно быть!) то, что если пользователь захочет увеличить немного масштаб изображения (image) в твите без того, чтобы кликать на нем и “переезжать” на MVC для подробного показа image, пользователь может просто перевернуть прибор в ландшафтный режим. Если все выполнено правильно, то вы получите эту возможность бесплатно (то есть не написав ни строчки кода).
Код для Swift 1.2 находится на Github. Код для Swift 2.0 находится на Github.
Продолжение следует…
Красиво получилось!! 🙂 Единственное, обратил внимание, что когда у твита есть значек фото или он отображается не полностью, то ссылка не подсвечивается синим.
Есть аналогичное Задание 4 в новом курсе по iOS 10 Winter 2017 https://bestkora.com/IosDeveloper/ios-10-swift-3/