Задание 4. Решение — дополнительные пункты 1- 5.

Screen Shot 2015-07-11 at 9.06.55 PM
Screen Shot 2015-07-12 at 10.17.36 AM
Это второе продолжение решения Задания 4.
Начало находится в посте Задание 4. Решение — обязательные пункты 1 — 4. 
Первое продолжение находится в посте Задание 4. Решение — обязательные пункты 5 — 10. 
Текст Задания  4 на английском языке доступен на  iTunes в пункте “Developing iOS 8 app: Programming: Project 4″.  Текст Домашнего задания на русском  языке доступен на 

Задание 4 iOS 8.pdf

Необходимо освоение Лекции 7, Лекции 9Лекции 10,  и Лекции 11
В этом посте подробно описывается выполнение дополнительных пунктов 1-5.
Код для Swift 1.2 находится на Github. Код для Swift 2.0 находится на Github.

Пункт 1 дополнительный

В секции Users вашего нового UITableViewController представьте список не только  пользователей, users, упомянутых в твите, но также и пользователей users, которые послали твит в первое место.

Мы уже это сделали при инициализации меншенов в классе MentionsTableViewController
Screen Shot 2015-07-10 at 2.34.36 PM
Вначале мы помещаем в массив userItems тех пользователей, которые послали твит в первое место, снабдив их лидирующим знаком «@», затем добавляем тех, кто упомянут в этом твите.

Пункт 2 дополнительный

Когда вы кликаете на user в секции Users, ищите не только те твиты, в которых “упоминается” этот user, но и твиты, где это пользователь user посылает твиты.

Используя синтаксис запросов в Twitter, мы изменим строку поиска, которая формируется при выборе элементов секции Users в в классе MentionsTableViewController в методе prepareForSegue
Screen Shot 2015-07-10 at 2.59.30 PM
.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
В результате получаем желаемый результат
Screen Shot 2015-07-10 at 3.02.30 PM

Пункт 3 дополнительный

Если вы “переезжаете” (segue), используя Show (а не  Unwind), добавьте какой-нибудь UI элемент, который всегда будет возвращать вас ( Unwind) к rootViewController в UINavigationController. Даже если вы используете Unwind (а не Show), то если вы выполняете дополнительный пункт, связанный с Collection View, используя Show segue, возможно, вы захотите реализовать “unwind to root” поведение в экранных фрагментах (scenes), на которые вы “переезжаете” через Collection View.

В подсказке № 3 для дополнительных пунктов Задания 4 нам подводят к очень интересной идеи использования полиморфизма при Unwind возвращении к корневому экранному фрагменту в  UINavigationController. Следуя этим рекомендациям нам понадобится всего одна строка кода для этого дополнительного пункта Задания. Посмотрим на нашу storyboar. Мы добавим во все экранные фрагменты, кроме корневых, кнопку Stop в правую часть навигационной панели, чтобы она нас возвращала к корневому экраном фрагменту из любой ситуации.
Screen Shot 2015-07-10 at 6.49.46 PM
Надо заметить, что два выделенных выше экранных фрагмента обслуживаются одним и тем же классом TweetTableViewController: один, Search Twitter, — корневой и ему не нужна кнопка возврата для Unwind, другой, Tweets from Mentions Search, — не корневой и ему нужна кнопка возврата для Unwind. Tут мы сталкиваемся с ситуацией описанной в подсказке В подсказке № 3 для дополнительных пунктов Задания 4, когда иногда вы хотите, чтобы появилась  кнопка “unwind to root”(вернуться в начало) , а иногда — нет (например, если вы уже находитесь в корневом View Controller, то вам, очевидно, эта кнопка не нужна).Вы можете попытаться управлять этой ситуацией в коде (с помощью if then предложений вы можете показывать или скрывать кнопки “unwind to root”), или вы могли бы использовать полиморфизм (polymorphism) и иметь в распоряжении корневой экранный фрагмент без кнопки “unwind to root”, при этом его Controller реализует “unwind to root@IBAction метод, который выполнил бы unwind для  “unwind to root” кнопок других экранных фрагментов (это не потребовало бы никакой реализации за исключением метода “unwind to root” в subclass non-root версии MVC). Другие экранные фрагменты (scenes) на storyboard имели бы кнопку, но не реализовали бы этот метод (потому что они используют superclass в качестве своего класса экранного фрагмента, а не subclass). Как часть этой технологии, возможно, вы захотите выполнять copy/paste целых экранных фрагментов  (и затем менять только их класс). Все это вы могли бы делать исключительно с unwinds.
Вот именно так мы сейчас и поступим. Мы создадим для экранного фрагмента Search Twitter subclass класса TweetTableViewController, который назовем RootTweetTableViewController  и содержит всего одну строку, необходимую для работы Unwind segue
Screen Shot 2015-07-10 at 7.03.59 PM
Все кнопки Stop в других Controller «подвязываем» к Action backToRoot:.
Запускаем — все работает. Если появятся новые Controller мы будем поступать точно также.
Код для Swift 1.2 находится на Github. Код для Swift 2.0 находится на Github.

Пункт 4 дополнительный

Вместо открытия urls в Safari, покажите их в вашем приложении путем “переезда” ( segueing) на Сontroller с UIWebView. Вам понадобиться обеспечить по крайней мере простейшее “управление браузером” с помощью элементов UI, которые приходят вместе с UIWebView (например кнопка “назад” (“back button”)).

Добавляем из палитры объектов новый View Controller на storyboard. Добавляем также из палитры объектов Web View и Activity Indicator View на новый View Controller и устанавливаем необходимые ограничения с помощью механизма Autolayout. А также кнопку Stop на навигационную панель для возврата на корневой экранный фрагмент
Screen Shot 2015-07-11 at 7.42.07 PM
Добавляем segue от Mentions к Web View (заметьте, что не от cell, а от самого View Controller) с идентификатором «Show URL«.
Screen Shot 2015-07-11 at 7.46.29 PM
Создаем новый класс WebViewController для нового Web View и не забываем его установить в Инсперкторе Идентичности.

Screen Shot 2015-07-11 at 8.04.25 PM

Добавляем outlets для Web View и Activity Indicator.

Screen Shot 2015-07-11 at 8.11.45 PM
Public API для этого класса будет URL web страницы, который мы будем запрашивать в методе «жизненного» viewDidLoad.
Screen Shot 2015-07-11 at 8.22.47 PM
Кроме того, мы добавили на навигационную панель справа стандартную кнопку Replay для возврата на предыдущую web страницу
Screen Shot 2015-07-11 at 8.26.34 PM
Делаем так, чтобы наш новый класс подтверждал протокол UIWebViewDelegate и делаем его делегатом Web View для того, чтобы использовать его методы для старта и завершения загрузки web страницы.
Screen Shot 2015-07-11 at 8.36.45 PM
Мы используем методы делегата для запуска и остановки как индикатора активности, расположенного в центре экрана, так и для сетевого индикатора на статусной панели.
В классе MentionsTableViewController, обслуживающем таблицу меншенов, мы вместо вызова Safari выполняет метод performSegueWithIdentifier
Screen Shot 2015-07-11 at 8.50.25 PM
В структуру Storyboard добавляем константу для идентификатора segue для Web View Controller:
Screen Shot 2015-07-11 at 8.54.46 PM
Запускаем приложение и получаем результат.
Screen Shot 2015-07-11 at 9.06.55 PM
Код для Swift 1.2 находится на Github.  Код для Swift 2.0 находится на Github.
Примечание. Если на web странице video или звук, приложение может иногда аварийно закончиться. Задала свойство  allowInlineMediaPlayback для webView,
Screen Shot 2015-07-12 at 9.24.57 AM
но этого, как оказалось,  недостаточно.

Пункт 5 дополнительный

Сделайте таблицу с “недавними поисковыми терминами” редактируемой (то есть позвольте пользователю использовать жест Swipe влево для удаления терминов, которые ему не нравятся).

В классе RecentsTableViewController реализуем метод делегата Table View, поддерживающий редактирование таблицы
Screen Shot 2015-07-12 at 10.01.00 AM

Вначале удаляем строку из Модели, а затем непосредственно из таблицы. Модель, класс RecentSearches  поддерживает удаление элемента с заданным индексом

Screen Shot 2015-07-12 at 10.07.50 AM
В результате получаем возможность удалять строки из таблицы с “недавними поисковыми терминами”.
Screen Shot 2015-07-12 at 10.11.20 AM

Код для Swift 1.2 находится на Github. Код для Swift 2.0 находится на Github.

Продолжение следует…

Задание 4. Решение — дополнительные пункты 1- 5.: 2 комментария

  1. Хороший пример полиморфизма в задании с Unwind переходом! WKWebView пришел на смену Web View. Они немного отличаются, но принцип остался тот же!

  2. Единственное с чем до конца не разобрался- это свойство ‘allowsBackForwardNavigationGestures’ у WKWebView. Оно предполагает навигацию по swipe, что у меня не сработало. Нашел возможную загвоздку- смешивание похожих жестов с interactivePopGestureRecognizer у NavigationController — попробовал отключить, self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
    И пока что это не дало результатов 🙂

Обсуждение закрыто.