На Лекции 11 курса Стэнфорда CS193p — «Developing Application for iOS» («Разработка приложений для iOS») Пол Хэгерти констатирует, что основные темы SwiftUI уже пройдены на предыдущих 10 Лекциях и сейчас студенты должны сосредоточиться на создании финального проекта. Пол Хэгерти выкладывает Лекции 11-14 в поддержку тем, которые не являются обязательными, но могут реально понадобится студентам в создании полноценных финальных проектов. На Лекции 11, первой из этой череды Лекций, рассматривается очень важная тема — Picker (средство выбора). Эта тема рассматривается в контекст нового приложения, не Memorize и не Emoji Art, это приложение под названием Enroute.
Приложение Enroute, по сути, использует API, которое доступно в интернете от компании FlightAware, и вы можете видеть, что оно действительно загружает информацию о рейсах. На рисунке в заголовке этого поста вы видите, что приложение Enroute загружает рейсы, которые находятся по пути в Сан-Франциско в международный аэропорт KSFO. Это код аэропорта. Нам сообщают, например, что SkyWest рейс прибывает сегодня в 11:42, то есть через 2 минуты. Он летит из Лос-Анджелеса. Нам сообщают обо всех рейсах, различных авиакомпаний, различных аэропортах отправления и т.д. В отличие от других демонстрационных примерах, которые мы разрабатывали «с нуля», на Лекции 11 мы получаем готовое начальное приложение Enroute, которое способно загружать рейсы с сайта FlightAware.
Наша задача на Лекции 11 состоит в том, чтобы разработать UI, с помощью которого можно будет осуществлять фильтрацию рейсов по аэропорту прибытия destination, по аэропорту отправления origin, по авиакомпании airline и по тому, находятся рейсы уже в воздухе или еще ожидают вылета на земле inTheAir. Надо сказать, типичная задача для многих приложений. И нам будет необходим Picker, чтобы сделать это, потому что мы собираемся выбирать аэропорты, выбирать авиакомпании и делать другие подобные вещи. Picker отлично для этого подходит. Весь демонстрационный пример Лекции 11 посвящен созданию такого UI в виде Редактора Фильтра с помощью Picker (95% времени) и Toggle (5% времени).
Но вначале решается, какую стратегию использовать для модального редактора, в данном случае Редактора Фильтра рейсов. Есть две главные стратегии для модальных редакторов похожих на Редактора Фильтра (в приложении Enroute) или на Редактор Палитры (в приложении Emoji Art).
Первая стратегия — «редактирование вживую», а вторая — «done / cancel». В первом случае вы редактируете напрямую те данные, которые «привязываются» к данным Редактора. В модальном View, выполненном в стиле «done / cancel» имеется локальная переменная, в которую копируются данные для редактирования, кнопка Done где-то в Редакторе, которая убирает (dismisses) с экрана Редактор и копирует все изменения, сделанные в локальной переменной во время нахождения Редактора на экране, обратно в редактируемые данные. У вас также будет кнопка Cancel, которая уберет (dismisses) с экрана Редактор без изменения этих данных редактирования.
В приложении Emoji Art в Редакторе Палитры PaletteEditor как только мы изменили имя палитры или добавили эмоджи, это фактически меняло нашу палитру в нашем документе. Это было “живое редактирование”. Наш модальный sheet редактировал вещи “в живую”.
Мы определенно не хотим этого в приложении Enroute. Мы не хотим тратить зря деньги и интернет-ресурсы путем выборки данных, которые соответствуют промежуточному выбору на пути к тому, что мы действительно хотим, Так что мы будем применять «Done» / «Cancel» стратегию к модальному sheet. И тут всплывает множество вопросов: «Как инициализировать @Binding переменные? Как передать значение от @Binding переменной в @State переменную?» Наоборот, то есть из @State переменной в @Binding переменную, мы знаем — нужно использовать $. А в обратную сторону? Во всех этих случаях на помощь приходит фактическая структура, связанная с Property Wrappers («Обертками свойства») — это переменная с «подчеркиванием» _. Тут профессор опирается на фундаментальную Лекцию 9, в которой подробно рассматриваются все переменные, связанные с Property Wrappers («Обертками свойства»).
Picker — очень интересный UI, он адаптирует свой «внешний вид» к той «среде» (Environment), в которую он попадает. Сам по себе Picker — это «колесико», если Picker — в форме Form, то это строка, которую не удается отредактировать без NavigationView вокруг Picker. Адаптируемость — это фундаментальный аспект SwiftUI.
А как создать Picker со значением nil, которое соответствует тому, что может быть любое значение из заданного списка — Any? На подобные вопросы есть ответы в Лекции 11.
Код демонстрационного примера для Лекции 11 находится на сайте курса CS193P и на Github для iOS 13 в папке Enroute L11.
Русскоязычный неавторизованный конспект Лекции 11, хронометрированный через каждые 5 минут, и представленный в виде PDF-файла, который можно скачать и использовать offline, а также в формате Google Doc доступны на платной основе.