Лекция 1. Начало работы со SwiftUI. Часть 1. CS193P Spring 2021.

Введение

Всем привет и добро пожаловать на курс CS193P Стэнфордского университета. Это курс о разработке приложений для таких устройств iOS, как iPhone и iPad, с использованием среды разработки под названием SwiftUI Это повтор курса, изначально предложенного моим студентам в весеннем семестре 2020 года. Меня зовут Пол Хэгарти. Я учил разработке приложений для iOS студентов Стэнфорда, конечно, в той или иной форме, около 10 лет, и я знаю, что вы приходите к этому изучению с очень разным бэкграундом, опытом программирования и разными ожиданиями того, что вы можете получить от этого курса. Так что на этот раз я решил сделать это небольшое вступление для студентов не из Стэнфорда, чтобы попытаться дать вам представление о том, чего ожидать от этого курса, прежде чем вы погрузитесь в него.  Этот семестр был очередным пандемическим семестром, предлагающим только удаленное обучение, так что вы получите этот курс точно в таком же виде, как мои стэнфордские студенты, на видео, и определенно в этом есть недостатки. Я люблю живые лекции, но на данный момент не могу этого делать, но есть некоторые преимущества и при просмотре лекций на видео. Например, у вас есть возможность сделать паузу и перемотать видео назад. Это отличная возможность, если у вас курс с таким техническим содержанием, как наш курс.

Конечно, у студентов Стэнфорда были супер интерактивные форумы этого курса и куча ассистентов профессора (ТА), готовых в любой момент им помочь, а вы будете этого лишены, но есть огромное множество действительно отличные ресурсов в Интернете. Есть очень яркое сообщество SwiftUI. И это не единственное место, где можно изучить программирование на iOS. Так что вам определенно следует найти все эти ресурсы и посмотреть эти видео, если вы уже этого не сделали. Этот курс проходит в своего рода «нарративном» формате, что хорошо работает для студентов, потому что они увязывают материал этого курса с другими своими курсами. Итак, мы работаем вместе, студенты и я. В процессе прохождения курса мы создадим пару прекрасных приложений, карточную игру и приложение для рисования. Я рассказываю лишь часть истории, когда я читаю Лекции и показываю демонстрационные примеры, а они участвуют в продолжении этой истории, когда делают свои домашние задания. Их домашние задания всегда строят на том, что я делаю на Лекции. Именно поэтому мы публикуем все описания домашних заданий и весь демонстрационный код на сайте cs193p.stanford.edu. Обязательно поищите их. Они абсолютно необходимы для получения максимальной отдачи от этого курса.

Курс CS193P — это не просто практический курс по программированию на iOS, но также курс о том, КАК работает сам SwiftUI. Как сконструирована система разработки SwiftUI очень важно для обучения наших CS (Computer Science — Информатика)  студентов, поэтому мы стараемся посвятить часть лекционного времени тому, КАК SwiftUI делает то, что он делает, а не только как повернуть в нем те или иные “ручки”, чтобы заставить его делать нужные нам вещи. Эти фрагменты о том, как устроен сам SwiftUI, будут “рассыпаны” по всем Лекциям.

Немного о предварительных требованиях к этому курсу. Студентам Стэнфорда рекомендовано взять хотя бы три, а на самом деле четыре вводных CS (Computer Science — Информатика) курса, так что они приходят на мой курс CS193P уже опытными программистами. В частности, одна из вещей, которую знают все студенты Стэнфорда, когда берут курс CS193P, это объектно-ориентированное программирование. Хотя на самом деле программирование с использованием SwiftUI не требует уж очень обширного применения объектно-ориентированное программирования, но концепции, которые вы изучаете в объектно-ориентированном программировании, такие, как экземпляры структур данных и инкапсуляция, действительно хорошие вещи, которые нужно знать, когда пытаешься понять, как работает SwiftUI. Кроме того, SwiftUI требует от вас изучения нового язык программирования под названием Swift. У стэнфордских студентов, которые берут курс CS193P, уже трижды или четырежды был опыт изучения нового языка программирования, так что для них изучение нового языка программирования не требует больших усилий. Но если для вас Swift будет вашим вторым языком программирования или вы — вообще начинающий программист и это ваш первый язык программирования, то вам понадобятся значительные дополнительные усилия, чтобы усвоить весь материал этого курса.

Из всего этого можно сделать вывод, что этот  курс не предназначен для начинающих программистов. Однако, если вы только начинаете программировать или вообще не являетесь программистом, то вам будет очень интересно посмотреть Лекции первых 2-х недель, чтобы составить представление о том, на что это похожа разработка приложения для iOS, потому что мы сразу приступаем к работе.

Студенты Стэнфорда отдельно не изучают язык программирования Swift, поэтому мы с самого начала не предполагаем, что они что-нибудь знают о Swift. Мы будем проходить его шаг за шагом и призываем студентов следовать за нами. Домашние задания действительно требует, чтобы вы следовали этим шагам. Независимо от вашего уровня и опыта программирования, вы должны повторять все то, что мы делали на Лекции,  по крайней мере, на первых нескольких Лекциях. 

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

Итак, поехали.

Начнем с рассмотрения того, что мы собираемся создать и как это будет демонстрироваться на  симуляторах iPhone. Две вещи, которые вы видите на экране, — это симулятор iPhone 11 — слева, и iPhone 8 — справа. Когда мы запускаем наше приложение, чтобы проверить, делает ли оно то, что мы хотим, конечно, мы можем подключить наше iOS устройство, наш iPhone или iPad, к Mac и запустить его там.

Но чаще лучше просто иметь возможность симулировать устройство и просматривать результаты запуска нашего приложения прямо на экране Mac.

Вот что позволяют эти симуляторы.

Они имитируют не только наше приложение, работающее на iPhone, но и большую часть самой iOS и его встроенных приложений. Например, приложение настроек “Установки” (Settings). Вы можете зайти в приложение настроек “Установки” (Settings) и установить вещи, которые могут влиять на то, как работает наше приложение.

Или приложение “Контакты”, если вам нужен доступ к адресной книге, или “Календарь” и т. д.

Все эти вещи,  с которыми, возможно, наше приложение захочет взаимодействовать, моделируются на iPhone.

Вот наше приложение, которое мы собираемся создать в этом семестре, оно называется  «Memorize» (“Запомнить”). У него еще нет значка приложения. Надеюсь, мы доберемся до этого в течение семестра. Я просто кликну на нем, чтобы запустить его.  Вот оно, и это игра. Я собираюсь щелкнуть здесь, на версии Хэллоуина.

Это игра на совпадение карт. Некоторые люди назвали бы эту игру “Concentration” (“Концентрация”),  иногда эту игру так называют. Мы будем называть ее “Memorize”. Это будет название нашего приложения «Memorize«. Это очень простая игра на совпадение карт. Вы кликаете на карточках, они переворачиваются,  а вы просто пытаетесь подобрать “совпадающие” карточки, на которых изображены эмоджи (смайлики). У нашей Хэллоуин версии оранжевая тема, хорошо ей соответствующая.

Эти две карты не совпадают, так что я должен продолжать поиски. Вы получаете небольшую вращающуюся анимацию. Это своего рода таймер, работающий в фоновом режиме. Он сообщает нам, как долго эта карта лежит “лицом” вверх. Мы явно хотим сократить это время и сопоставить карты как можно быстрее.

Так что теперь я смог найти совпадение. Вот оно.

Обратите внимание, что на экране нет “заработанных” очков, так как я оставил это для вас в домашнем задании. Вы должны решить, как распределять баллы на основе этого таймера, который показывает, как быстро подбираются ”совпадающие” карты.

Возможно, вы захотите “наказать” игрока, который мог бы обнаружить “совпадения”, но не сделал этого. Так что вы можете проиграть здесь много очков, щелкая на картах и пытаясь найти совпадения, но вы можете также набирать очки, потому что хорошо запоминаете карты и их местоположение. «О да, я точно знаю, где эта карта расположена. Это было прямо там”. Вы собираетесь щелкнуть и сопоставить эти карты, а таймер уже отмечает, сколько времени у вас карта открыта “лицом” вверх, и так далее.

Я оставляю все это вам. Я не хочу предвзято относиться к любой предложенной вами конкретный канонический реализация начисления очков. Так что это полностью зависит от вас.

Этот пользовательский интерфейс может делать и другие вещи. Мы можем создавать новую игру. Можем перезапустим все карты “лицом” вниз и полностью их перетасовать.

Вы видите, что есть много анимаций в этой игре. В SwiftUI очень легко сделать анимацию.

Вернемся на первый экран, эта часть UI позволяет выбрать другую тему. У нас был Хэллоуин. Выберем Транспорт. Теперь мы подбираем смайлики для автомобилей. Там было совпадение. Есть еще одно совпадение.

Мы можем также редактировать эти темы. Я могу кликнуть на кнопке “Edit” («Редактировать»), а затем кликнуть на смайликах, принадлежащих этой теме, и появится приятный интерфейс для добавления смайликов в мою тему, изменения цветов темы, возможно также изменение количества пар “совпадающих” карточек, названия темы.

Вы будете на 100% делать весь этот пользовательский интерфейс (UI) в вашем домашнем задании. К тому времени, когда мы закончим с этим всего через несколько недель, у вас  уже будет умение создавать даже такие сложные UI, как этот. Очевидно, что нам нужно изрядно потрудится над этим UI. И мы не будем создавать это все только на этой неделе во время Лекций. Мы начнем с малого, а затем будем двигаться постепенно, шаг за шагом.

В симуляторе, расположенном справа у меня есть версия приложения “Memorize”, которую мы создадим на этой неделе.

Вы видите, что у него есть карты, которые я могу кликнуть, и они действительно переворачиваются, хотя и не анимируют. Очевидно, там нет таймера. Кроме того, если я все переверну все карты, то вы заметите, что там нет двух одинаковых карт. Все 12 карт — совершенно разные.

Так что мы не можем играть в карточную игру “на совпадение”, так как у нас нет подходящих “совпадающих” карт. В общем всю логику карточной игры “на совпадение” мы собираемся сделать на следующей неделе.

На этой неделе мы просто попытается создать наш UI, и пусть он выглядит как показано на симуляторе справа. Очевидно, мы ничего не делаем из того сложного UI, который был вам продемонстрирован на симуляторе слева, мы просто пытаемся получить наши карты. Правда, мы добавим здесь пару вещей, которых нет в нашей окончательной версии игры Memorize. Эту кнопку с плюсом, которая добавляет карту. Она позволит добавить сколько угодно карточек, поэтому мы хотим, чтобы наш пользовательский интерфейс (UI) прокручивался вниз и мы смогли посмотреть на карточки, не уместившиеся на экране.

В то же время карты на симуляторе слева не прокручиваются. Кстати, это действительно заметно, если мы развернем симулятор слева в ландшафтный режим с помощью кнопки вверху. На этом симуляторе карты меняют немного размер, чтобы полностью “вписаться” в предоставленное пространство.

В нашей версии, представленной на симуляторе справа, вращение в ландшафтный режим также работает, но все равно нужно прокручивать, потому что мы не можем вместить все карты в предоставленное пространство. Карточки в этой версии справа имеют фиксированный размер.

Сначала я хотел предложить вам создать в вашей домашней работе кнопку “Shuffle” (“Перетасовать”), которая перетасовывает карты, расположенные на экране.

Но потом решил предложить вам сделать что-то более амбициозное, чем простая перетасовка карт. Вы должны обеспечить простейший выбор темы, никак не похожий на тот, который мы видели слева, из того, что вы изучите на первой неделе. Кроме того, вы, вероятно, заметили, что при перетасовке карт (shuffle) выполняется небольшая анимация, которую я отложил на более поздние домашние задания, так что вам не придется делать анимацию в вашем домашнем задании. Мы поговорим о возможностях анимации в SwiftUI через пару недель.

Инструмент, который мы будем использовать для создания наших приложений называется Xcode. Это универсальная среда для разработки приложений, которая позволяет редактировать ваш код, запускать его на выполнение, видеть пользовательский интерфейс по мере его создания, производить отладку приложения и так далее. Все в одном месте. Давайте здесь кратко поговорим о том, как мы получаем Xcode.

Нам нужен Xcode. А поскольку это приложение для Mac, конечно, мы можем пойти в Mac App Store. Если вы перейдете в приложение Mac App Store и просто в строке поиска введете “xcode”, то получите в самой верхней строке приложение Xcode.

Вместо кнопки “Open” будет кнопка “Get”. Если вы кликните на ней, то начнется скачивание этого приложения. Затем вы просто кликаете на нем, и оно уже будет в рабочем состоянии. Это бесплатное приложение, оно ничего не стоит. Кроме того, вы можете присоединиться к программа для разработчиков Apple за 99 $ в год. О том, что это вам дает мы поговорим через мгновение, но это не обязательно. Для нашего курса этого не требуется, ни одно из приложений, которые мы будем создавать на этом курсе не требует присоединения к программе для разработчиков Apple. Так что это бесплатно.

Если ты достаточно смелы и авантюрны и хотите попробовать бета-версии Xcode, которые постоянно выходят каждые несколько недель, то вы, конечно, можете это сделать. Я покажу вам вкратце, как это сделать.

Просто откройте свой Safari, перейдите на сайт developer.apple.com. Фактически, мы можем сразу перейти по ссылке developer.apple.com/download. Наверное, это самый быстрый способ добраться туда. Вы видите, что здесь есть загрузки бета-версии программного обеспечения как Mac OS, так и iOS

Но также, в разделе приложений Applications, вы видите Xcode 12.5 beta 3.

Эта бета-версия будет обновляться со временем. Вы просто кликаете на кнопке “Download”  (“Cкачать”) и можете запустить его. Я ничего не делаю в этом курсе, что потребовало бы этой бета-версии, так что совершенно нормально использовать версию Xcode из App Store. Возможно, вы начнете использовать бета-версии, когда почувствуете себя более уверенно и захотите быть в курсе событий. В этом случае не стесняйтесь переключаться на бета-версию, если хотите. Как только вы получили Xcode на вашем Mac, кликаем по нему и запускаем. Я беру бета-версию Xcode 12.5 здесь. Сейчас  Xcode 12.5 находится в уже в App Store.

Когда мы это делаем, мы получаем эту заставку.

Вне зависимости от того, бета-версия у вас или нормальная, вы всегда получите эту заставку. Очень простая стартовая точка в Xcode: справа у нас представлены все наши последние проекты. То есть проекты, над которыми мы работали, будет храниться в списке справа. Слева у нас есть три варианта: создание нового проекта, клонирование проекта из Git репозитория или поиск существующего проекта, которого нет в списке справа, что довольно редко встречается.

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

На самом деле есть два способа создать новый проект, используя эту заставку. Один — создать его здесь и использовать первую опцию. Второй — это клонировать проект и использовать вторую опцию. При этом исходный код проекта находится где-нибудь в Git репозитории.

Я собираюсь немного поговорить об управлении исходным кодом и репозиториях позже в этом семестре, но пока мы, очевидно, просто создавать наш самый первый проект в истории, нажав кнопку Create a new Xcode project («Создать новый проект Xcode «). Здесь еще есть опция Open a project or fileОткрыть проект или файл»), но я не собираюсь ей пользоваться.

Итак, щелкаем на  Create a new Xcode projectСоздать новый проект Xcode«).

Нас сразу же спрашивают: какой проект вы хотите создавать?

Xcode может создавать не только приложения для iOS, которые, очевидно,  нам и нужны, но также приложения для Mac OS:

 … для Apple Watch

для Apple TV:

и даже для много платформенных приложений, которые запускаются как на Mac OS, так и на iOS:

Мы будем это делать при разработке второго большого приложения, которые мы создадим позже в этом семестре. Но сегодня мы займемся приложениями для iOS. Даже в iOS есть различные приложения. Большую часть времени мы будем использовать для этого просто базовое «приложение» App:

Но позже в этом семестре мы собираемся создать “Document App” («Приложение для документов»), но есть и другие шаблоны приложений. Вы можете исследовать некоторые из них для вашего финального проекта.

Но мы собираемся создать iOS приложение. Просто сделайте в этом месте паузу и лишний раз убедитесь, что вы имеете пару “iOS — App”, когда вы создаете свое приложение, прежде, чем кликнуть на “Next” («Далее»). Когда вы это сделаете, вам зададут несколько вопросов о приложении для iOS, которое вы хотите создать.

Первый вопрос:  как вы хотите назвать своё приложение? Вы должны заполнить поле Product Name. Мы знаем, что наше приложение называется Memorize.

Второй вопрос — это команда разработчиков Team, создающая это приложение. Возможно, это будете вы.

Если вы попадаете на этот экран и раньше не использовали Xcode, то, вероятно, во второй строке будет находиться что-то вроде “Create a team” (“Создай команду”). Вам нужно кликнуть на этом и создать команду разработчиков. Это действительно очень легко сделать, вам просто нужен Apple ID, который обеспечивает нам обычный вход (login) в iCloud. Опять же, денег это никаких не стоит.

Вы просто регистрируете эту команду разработчиков с этим идентификатором Apple iCloud и это все. Теперь вы можете разрабатывать и запускать приложения с этой командой разработчиков.

Далее у вас будет третья строка, в которой вы должны задать идентификатор организации Organization Identifier. В нашем случае вы — это и есть “организация”. По сути, это организация, в которой вы работаете, но вы — студент. Если вы не являетесь студентом Стэнфорда, то это может быть компания, в которой вы работаете. Третья строка должна идентифицировать ту организацию, которая работает над этим приложением. Если вы — физическое лицо, то я рекомендую использовать в этом поле то, что называется обратной нотацией DNS. Может быть, ваш адрес электронной почты, или, если вы — студент Стэнфорда, то edu.stanford.cs193p. [ваш SUNetID] вместо instructor (инструктора).

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

По сути, вам нужно просто обеспечить в этом поле уникальную вещь, которая идентифицирует группу, работающую над этим приложением. Xcode быстро комбинирует имя приложения Product Name с именем организации Organization Identifier и получает Bundle Identifier (уникальный идентификатор) для этого приложения.

В следующих трех строках у вас есть возможность выбрать Interface между новый способ, SwiftUI, разработки приложений для iOS и старым способом, который называется Storyboard.

У меня всего 10 недель, чтобы показать вам разработку приложений на iOS, и я не могу показать вам оба этих способа. 

Новый способ SwiftUI, это действительно очень новый способ, который появился всего пару лет назад, но он очень мощный, и это тоже принесло определенные преимущества при обучении по сравнению со старым способ проектирования.

Когда вы создаете приложение, у вас всегда должны быть включены эти три кнопки:

Способ создания UI (Interface):  

  • SwiftUI —  новый способ создания UI,
  • Storyboard — старый способ создания UI,

Способ создания приложение (Life Cycle):

  • SwiftUI App — новый способ создания приложения,
  • UIKit App — старый способ создания приложения,

Также вы можете смешивать новый способ создания UISwiftUI —  со старым способом создания приложения — UIKit App. Это странно. но так можно делать и мы так делали так год назад, как только появился SwiftUI. На этом курсе мы этого делать не будем. Мы всегда будем создавать SwiftUI App приложения.

Поскольку мы выбрали для создания UI — SwiftUI , а для создания приложения — SwiftUI App, язык программирования — Language  — у нас только один — Swift:

SwiftUI полностью зависит от языка программирования Swift, который является новым языком программирования приложений на устройствах Apple, и я не буду исходить из того, что вы его знаете. Я буду обучать вас ему “с нуля” весь этот семестр.

Если бы мы выбрали здесь старый способ создания UIStoryboard — то у нас появилась бы возможность выбора языка программирования Language между Objective-C, который изначально был изобретен для написания приложений на устройствах Apple, и новым языком программирования Swift.

Но опять же, из-за временных ограничений в этом курсе у нас всегда будут настроены одни и те же три кнопки на разработку SwiftUI приложений и язык программирования всегда будет один — Swift.

И последнее замечание касается переключателей, расположенных в самом низу.

Убедитесь, что все они выключены для нашего первого приложения, но позже мы собираемся посмотреть на переключатель Core Data. Это объектно-ориентированная база данных.

У меня нет времени показывать, как проводится тестирование с использованием фреймворка SwiftUI, но это чертовски здорово. Это позволяет вам тестировать не только сам код,  но и ваш пользовательский интерфейс UI, чтобы убедиться что ваш UI выглядит как и положено.

Но опять повторюсь, пожалуйста, выключите все эти переключатели  для первой версии нашего приложения Memorize.

Когда мы кликаем на кнопке “Next” (“Далее”), то нас просто спрашивают, где в файловой системе мы собираемся разместить файлы нашего проекта?

Настоятельно рекомендую разместить файлы проекта в вашей Home директории в папка под названием Developer. В результате все ваши проекты должны собираться здесь, в Home/Developer папке. Это каноническое место для размещения проектов. Вы видите, что Finder даже помещает туда значок молотка, он признает это как стандартный вид папки для размещения Xcode проектов.

В нижней части этого экрана размещена система управления версиями исходного кода (Source Control):

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

Система управления версиями исходного кода (Source Control) прекрасно подходит для управления версиями вашего приложения во время работы над ним, но она исключительно ценна для команд (Team), совместно разрабатывающих одно приложение. Когда вы работаете над одним и тем же проектом с командой из пяти программистов или даже сотни программистов, как вам организовать работы так, чтобы вы не “наступали друг другу на пятки”?

Эта полная система управления версиями исходного кода (Source Control) обеспечивает механизм проверки вашего кода, внесения изменений, и повторной перепроверки вашего кода, чтобы убедиться, что он не конфликтует с кодом других программистов в вашей команде и так далее.

Опять повторюсь, коротко поговорим об этом позже в этом семестре, но сейчас для нашего первого приложения я определенно хочу, что Source Control был выключен. Если вдруг у вас Source Control был включен, то экран определенно будет выглядеть немного по-другому, но вы должны выключить Source Control.

Так что оставим это, и кликаем на кнопке “Create”  («Создать«) …

… и “вуаля” :

Xcode создал для нас наше первое приложение.для iOS. Поздравляю вас, вы создали свое первое приложение для iOS.

Это главный экран Xcode. Вы будете “жить” в этой среде разработки очень долго в течение этого семестра, поэтому я собираюсь потратить некоторое время на то, чтобы рассказать обо всех составляющих частях UI среды разработки Xcode.

Начнем прямо сверху с этой  маленькой забавной комбинацией кнопок.

Эта комбинация кнопок посвящена тому, как вы запускаете свое приложение. Но, первое, что вы должны сделать — это выбрать, где вы хотите запустить ваше приложение:

Прямо сейчас там написано, что приложение будет запускаться на  iPad Touch (7-го поколения). Вот где Xcode запустил бы приложение, если бы я запустил его прямо сейчас.  Но я собираюсь кликнуть на этом поле, и вы увидите, что я могу выбирать устройство для запуска своего приложения. 

Это может быть устройство iOS, подключенное к моему Mac. (Прямо сейчас у меня нет никаких подключений) или я могу запустить его на одном из этих отличные симуляторы, которые мы уже видели.

В  этом списке есть симулятор iPhone 8, iPhone 11. Мы собираемся запустить наше приложение на iPhone 12 mini, моем любимом iPhone. Вы просто выбираете, где хотите запустить приложение и нажмите на кнопку воспроизведения Play:

 А затем, когда вы закончите работать в вашим приложении на одном из устройств, вы кликнуть на кнопке Stop.

Так что вы можете запускать приложение с помощью кнопки Play и останавливать его с помощью кнопки Stop. Play и Stop. Play и StopДавайте запустим приложение на симуляторе iPhone 12 mini. Вот оно.

Он просто говорит: Hello, World!” («Привет, мир!»). Те из вас, кто смотрел на наш код, наверное говорили : «Хм, держу пари, это приложение говорит: Hello, World!” («Привет, мир!»).«

И на самом деле он говорит: Hello, World!” («Привет, мир!»). Это то, что написано в этом приложении. В остальном это просто большое пустое пространство.

Это круто, что мы смогли это сделать, мы также можем вращать наш симулятор с помощью кнопки, расположенной на нем:

И это прекрасно:

Приветствие Hello, World!” («Привет, мир!») автоматически центрируется. Мы обнаружим, что для того, чтобы при вращении устройства наш пользовательский интерфейс менялся нужным образом, нам придется написать очень мало кода.

SwiftUI в значительной степени справляется вместо нас  с такими вещами, как правильное центрирование и все такое.

Но я снова хочу напомнить, что это полноценный симулятор iPhone. Я могу переключиться в нем на другое приложение и запустите, например приложение “”Settings” (“Настройки”):

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

Это полная симуляция. Итак, когда когда мы закончим работать с нашим приложением на симуляторе, мы кликаем на кнопке Stop

 

… и приложение остановится, оно перестанет работать.

У меня в Xcode меню спрятано, чтобы дать вам больше места, но, очевидно, что в Xcode есть большое меню, и мы будем им пользоваться. Мы будем изучать его по ходу дела.

Вас может испугать такое большое количество пунктов меню, но опять же, мы будем очень медленно их открывать. Это не будет так пугающе.

В нашей строке с кнопками есть есть небольшая замечательная статусная строка, которая просто говорит вам, что происходит.

В данном случае в ней сообщается, что мы только что завершили запуск Memorize. В этой чудо-статусной строке будет сообщаться, когда Memorize компилируется и все прочее.

Давайте посмотрим на самую левую область Xcode:

Она называется Навигатором (Navigator) и делает то, что говорит её название: позволяет перемещаться по вашему приложению. Вы можете делать это множеством разных способов. Маленькие значки в верхней части Навигатора позволяют вам выбирать эти разные способы навигации по проекту, и по умолчанию выбирается  навигация по файлам.

Это все файлы, которые есть в нашем приложении. Эти четыре файла были созданы для нас Xcode, чтобы мы начали разработку приложения, и я собираюсь рассмотреть все четыре файла через мгновение.

Но мы также можем использовать и другие способы навигации: 

  • путем поиском по всему нашему проекту:

  • или, если мы отлаживаем проект, то мы можем посмотреть что происходит во всех наших точках останова:

  • и так далее.

Мы увидим все эти разные способы навигации по ходу нашего курса.

Все области в Xcode могут быть изменены. Просто возьмите и с помощью мыши делайте области больше или меньше, распределяя пространство по своему усмотрению.

Вы также можете скрывать и показывать области с помощью этой маленькой кнопки.

Часто, когда вы углубляетесь в редактирование, вам действительно не нужно переключаться между файлами, но особенно потому, что в верхней части области редактирования вы видите вкладки, соответствующие файлам, с которыми вы ранее работали:

В данном случае на вкладках указы файлы ContentView.swift и MemorizeApp.swift, и вы можете переключаться между ними:

Действительно вам не так уж сильно нужна область Навигатора, если вы не собираетесь искать что-то особенное.

Справа расположена светло-серая область, которая называется Инспектором (Inspector).

Я собираюсь показать  вам её чуть позже.

В центре находится Главное окно редактирования с двумя панелями.

Обычно слева у вас будет ваш исходный код здесь слева, а справа — один или даже несколько других вспомогательных окон. Это конкретное маленькое пространство справа — очень крутое.Это предварительный просмотр Preview вашего пользовательского интерфейса (UI).

Оно действительно показывает вам, как выглядит ваш UI без необходимости запускать приложение на симуляторе, и он показывает вам это в основном в реальном времени (то есть по мере редактирования UI в коде).

Иногда он делает паузу. И именно это состояние сейчас показано: Automatic preview updating paused («Автоматическое обновление предварительного просмотра приостановлено»).  Вот почему мы не видим здесь наше приветствие Hello, World!” («Привет, мир!»).

Но мы можем возобновить предварительный просмотр Preview в любое время с помощью кнопки “Resume («Возобновить»).

Когда мы возобновляем предварительный просмотр Preview, это, по сути, похоже на запуск небольшого симулятора на панели предварительного просмотра и может потребовать некоторого времени:

Мы можем немного уменьшить масштаб нашего UI. И вот мы получили наше маленькое UI Hello, World!” («Привет, мир!»). Мы можем распределить пространство в Главном окне редактирования лучше, если мы хотим.

Мы увидим, как этот предварительный просмотр Preview всегда используется при разработке UI. Это действительно мощная, потрясающая система. В верхней части Главного окна редактирования есть небольшая строка, которая говорит, где мы находимся.

В частности, нам сообщают, где находится наш курсор. Если я щелкну на body, строка сообщает, что мы находимся на body.

Если я щелкну внутри ContentView_Previews, строка говорит, что мы внутри  ContentView_Previews.

Вы даже можете кликнуть в информационной строке на положении курсора и в открывшемся окошке перемещаться куда хотите:

Можете прыгать вниз и обратно наверх и так далее:

Эта информационная строка показывает, где находится наш курсор.

Но есть одна очень крутая вещь, касающаяся всех этих 3-х областей: область предварительного просмотра Preview, панель основного редактирования кода и этот инспектор Inspector будут все время синхронизироваться.

Если я кликну в окне редактирования кода на строке Text(«Hello, world!»), то Xcode не только выберет и выделит эту строку кода, но и выделит синей линией UI элемент Text(«Hello, world!») в области предварительного просмотра Preview и задействует область инспектора Inspector для показа того, какой-то UI используется для просмотра или редактирования, и позволит изменять его атрибуты.

Если я уйду прочь со строки кода строки Text(«Hello, world!»), то и предварительный просмотр Preview, и инспектор Inspector перестанут выделять эту строку и показывать атрибуты, так как ничего не нужно проверять и изменять.

Возвращаемся назад, и все показывается:

Если я кликну в стороне в окне редактирования исходного кода и дважды кликну на «Hello, world!» в предварительном просмотре Preview, то этот UI элемент выбирается в коде и будет показан в инспектор Inspector.

Вы можете работать напрямую с предварительном просмотре Preview  и просить показывать в коде любой UI элемент, расположенный на Preview. Все три панели тесно взаимосвязаны и будут показывать вам все до тех пор, пока предварительный просмотр Preview не будет “поставлен на паузу”. Мы можем редактировать или изменять UI элементы в любой из этих трех панелей.

Например, у нас есть Text(«Hello, world!»)(«Привет, мир!») в нашем коде, а мы изменим этот код  на Text («Hello, CS193p!») ( «Привет, CS193p!»).

Это действительно круто, когда я меняю в коде свой UI элемент, он меняется на предварительном просмотре Preview и в инспекторе Inspector в реальном времени. И так будет всегда до тех пор, пока предварительном просмотре Preview не приостановлен. Но если даже это будет приостановлено, вы всегда можете кликнуть на кнопке “Resume” (“Возобновить”) и синхронизация будет продолжаться.

Надо сказать, что инспектор Inspector — это довольно мощный механизм. Это не просто изменение текста Text, вы также можете изменить шрифт, цвет шрифта и т. д. Вы даже можете здесь изменять некоторые отступы padding.

Вы видите эту маленькую синюю точку в разделе Отступы (Padding), это говорит о том, что у меня есть отступы. И если мы посмотрим на код, то увидим там .padding():

Если я выключу этот синий кружочек в инспекторе Inspector в разделе Отступы (Padding), то .padding() пропадет и в исходном коде, они берутся из инспектор Inspector:

Если я снова включу в инспектор Inspector в разделе Отступы (Padding), но только для вертикального заполнения, то и в коде я получаю Отступы (Padding) по вертикали:

Опять же, нас не беспокоит,  что все это значит, но суть в том, что как только меняем что-то в инспектор Inspector, мы меняем это и в коде.

Это наш небольшой тур по Xcode.

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

Вернемся к тому, что я обещал сделать, то есть посмотрите на эти четыре файла, которые Xcode создал для нас, когда мы создавали этот проект.

Начнем с файла Assets.xcassets.

Когда я говорю Assets (Ресурсы), это означает такие вещи, как изображения, звуки и видео, это виды ресурсов. Когда мы создаем приложение для iOS, мы перетаскиваем эти ресурсы в Assets и даем им имена.

В белом столбце у нас будут названия ресурсов, а справа от него — сами фактические ресурсы, и вы увидите, как там появятся сами изображения. Некоторые ресурсы более сложные, чем другие. Например, такие, как значок вашего приложения  AppIcon — это довольно сложный ресурс, так как в нем много разных разрешений:

Эти разрешения зависят от окружающей среды, будь то iPad или iPhone, или вы в Spotlight, или вам сообщают, что только что пришли уведомления Notifications на ваш iPhone для этого приложения и т.д.  

Если у вас есть приложение, особенно приложение, которое вы собираетесь разместить в магазине приложений App Store, то вам, наверное, следует попросить художника или кого-нибудь еще, кто мог бы сделать прекрасные красивые иконки для вашего приложения, которые бы хорошо выглядели для этих различных разрешений. Мы больше не будем смотреть на ресурсы, но мы собираемся использовать их позже, когда захотим добавить изображения в наше приложение.

А что насчет файла Info.plist?

По сути, это настройки вашего приложения, но это довольно грубый способ отредактировать настройки в Info.plist напрямую, мы обычно так их не редактируем. Вместо этого, мы кликаем на самом проекте и получаем приятный интерфейс для редактирования этих же самых настроек прямо здесь:

О каких настройках идет речь?

Например, работает это приложение на iPhone?  — Да. А работает приложение на iPad? — Да. Приложение работает на Mac? — Нет.

Мы не создаем это наше первое приложение Memorize для запуска на Mac. Следующее приложение, которое мы создадим, мы будет запускать его Mac. Следующая настройка относится к тому, на какой версии операционной системы мы будем запускать наше приложение: iOS 14, iOS 13, iOS 11?

Чем меньше версия, тем меньше новых функции, которые мы можем использовать.

Когда вам нужно поменять что-то в настройках проекта, то лучше это делать с этими приятными переключателями этого пользовательского интерфейса и всем остальным, чем менять их в Info.plist напрямую:

В действительности мы вообще не смотрим на наш Info.plist. Мы почти всегда щелкаем на нашем приложении, в данном случае Memorize, если мы хотим изменить настройки проекта и в 99% случаев вам вообще не нужно менять никакой из этих параметров. Они просто по умолчанию установлены правильно.

Еще нам осталось разобраться с этими двумя файлами в нашем Навигаторе.

Оба этих файла имею расширение .swift, это файлы нового языка программирования Swift, и я собираюсь рассказать вам об этом языке программировании Swift “с нуля”.

Вот этот файл MemorizeApp.swift, я не буду рассматривать его слишком подробно, он действительно не имеет большого значения. Но несколько замечаний по этому поводу я сделаю. Это наша основная программа.  В языке программирования C у вас есть main.c, который является основным модулем C и в котором находится ваше приложение. Когда приложение запускается, это модуль начинает выполняться. У нас в Swift то же самое. Потому что мы поместили сюда @main, это становится нашей основной программой:

Мы не слишком беспокоимся о выделенном коде:

Здесь главное отметить, что в середине этого кода находится вызов ContentView ( ),  и это другой .swift файл ContentView.swift, именно он будет описывать, как выглядит наше приложение.

И если мы смотрим наше приложение на симуляторе, то вся территория экрана независимо от того, какое это приложение, это наш ContentView.swift файл.

И действительно наша  основная программа @main говорит о том, как называется эта основная территория?

В нашем случае это ContentView ( ), то есть весь код, находящийся в файле ContentView.swift, воспроизводит весь UI нашего приложения.

На самом деле в файле ContentView.swift находится немного больше, чем весь этот код. В самом низу файла находится такая маленькое вещь с именем ContentView_Previews.

Этот ContentView_Previews код “склеивает” наш на предварительном просмотре Preview и наш ContentView. Так что на самом деле только весь код ContentView рисует наше приветствие «Hello there, CS193p!»(«Привет, CS193p!»).

А к “клею”- коду ContentView_Previews мы почти никогда даже не прикасайтесь не будем. Я покажу вам немного позже на лекции на этой неделе, как мы могли бы немного изменить ContentView_Previews, но в большинстве случаев мы не будем обращать на него внимания. 

Я обычно люблю просто убрать его в самый низ и не видеть его.

Теперь этот “клей”- код ContentView_Previews находится в самом низу и я даже не смотрю на него. Заметьте, кстати, что когда я так быстро делаю изменения, наш предварительный просмотр Preview остановился. Для того, чтобы я мог возобновить работу предварительного просмотра Preview, нужно кликнуть на кнопкеResume” (“Возобновить”), и Preview продолжится.

Ладно, вот и все. Это ваш тур по Xcode.

Теперь мы сосредоточимся на этих строках кода и попробуем понять, что каждая строка кода здесь делает.

Я убрал Навигатор и вернул приветствие «Hello there, CS193p!» ( «Привет, CS193p!») на старое  «Hello, world!» ( «Привет, мир!»).

Давайте сосредоточимся на ContentView и просто пройдемся по его коду строка за строкой.

Самая верхняя строка: import SwiftUI.  Это легкая строка, это похоже на include или import на других языках программирования. Мы просто сообщаем, что этот файл собирается использовать пакет Swift-кода с именем SwiftUI. Он сделан Apple и поставляется со всеми устройствами iOS и с MacOS и Apple Watch и со всеми другими устройствами Apple.

В нашем коде пакет SwiftUI присутствует потому, что мы выполняем разработку пользовательского интерфейса (UI) в этом файле, но не каждый файл, который мы создаем, будет связан с разработкой UI.

Например, файлы, которые мы создадим для отображения логики нашей игры, сопоставляющей карты, находящей “совпавшие” и ведущей счет игры, не связаны с разработкой UI. Это логика, и в таких файлах мы не будет импортировать SwiftUI.

Одной из замечательных особенностей SwiftUI является как раз то, что он очень четко разделяет логика и создание пользовательского интерфейса UI.

Но в нашем случае мы работаем над UI и даже не собираемся до следующей недели начинать разрабатывать нашу игровую логику, так что все это наш пользовательский интерфейс Ui, и мы, конечно, хотим импортировать SwiftUI.

Вот код, который генерирует UI:

И здесь создается структура данных struct — это сокращение от структуры данных (data structure). Структуры данных есть в большинстве языков программирования.

Структуры struct — по сути — коллекции переменных, и у C есть эти структуры, и у многих других языков программирования, иногда они могут не называться struct, но это всегда  есть какой-то набор переменных.

Коллекция переменных в Swift — довольно мощные, потому что у нас не только могут быть переменные в нашей структуре struct — и вы видите одну из них прямо здесь, —  переменную var body, о которой я поговорю позже.

Но в Swift структуре struct могут быть и функции наподобие func foo, там есть код, это совершенно законно. 

Мы будем рассматривать функции func, особенно на следующей неделе, но, как оказалось, на самом деле нам они не будут часто нужны при построении пользовательского интерфейса UI. Но у структур struct могут быть функции.

Многим из вас это может показаться объектно-ориентированным программированием, потому что объектно-ориентированное программирование — это некоторые переменные данных vars, инкапсулированные вместе с их функциональностью. Мы называем такие функции в объектно-ориентированном программировании методами. И Swift действительно поддерживает объектно-ориентированное программирование, и мы даже будем использовать объектно-ориентированное программирование особенно для того, чтобы связать нашу логику с нашим пользовательским интерфейсом UI. Вы увидите это на следующей неделе.

Однако ничего из того, что вы видите на этой неделе не является объектно-ориентированным программированием. В частности структуры struct, хотя они могут иметь переменные var и функции func с использованием этих переменных, но они не являются объектно-ориентированные вещи.

Это не классы class. У структур struct нет наследования (inheritance) или чего-нибудь подобного, структуры struct — это совершенно другие вещи, именно о них я собираюсь вам рассказывать и именно они приводят к другого рода программированию, которое мы называем функциональное программирование.

Swift поддерживает оба программирования: и объектно-ориентированное программирование, и функциональное программирование.

Мы используем в качестве дизайн-модели при создании пользовательского интерфейса UI функциональное программирование, а объектно-ориентированную дизайн-модель используем для подключения нашей Модели, нашей логики, к этому UI. Сегодня мы будем говорить только о функциональном программировании.

Нам явно не нужна эта функция func foo, все равно она ничего не делать. БУМ! — убираем ее:

Что следует за structstruct — это ключевое слово. Все наши ключевые слова, конечно же, будут в коде пурпурного цвета, их легко можно узнать.

Следующее слово — ContentView:

Это просто имя этой структуры данных struct, оно может быть любым, каким захотите. Когда Xcode создавал приложение, которое говорит: «Hello, world!» ( «Привет, мир!»), он действительно не знал, что мы собираемся создать приложение Memorize, поэтому он назвал эту вещь ContentView, так как, по сути, это и есть содержимое всего нашего приложения.

Пока я оставлю это имя как есть, но по ходу дела, вероятно, переименую его на что-то типа  MemorizeView, то есть на немного более конкретное, связанное с тем, что мы делаем, но в любом случае ContentView — это просто имя этой структуры struct, ничего особенного в этом нет.

Вот следующее слово —  : Viewочень даже особенное:

Когда вы определяете структуру struct с : View, это означает, что эта структура struct “ведет себя” как View. Я же сказал, что это функциональное программирование, а в функциональном программировании “поведение” вещей, то есть как вещи “ведут себя”, имеет решающее значение.

Большая часть того, как “ведет себя” вещь, — это функции func, которые вы можете вызвать на тех вещах, которые определяют, как они “ведут себя”. А что касается хранения данных, то функциональное программирование ничего не говорит о том, как на самом деле хранятся данные. Оно может немного поговорить о том, что представляют собой какие-то данные и какие данные должны быть в этой структуре struct, но оно не говорит о том, как следует хранить эти данные, хранятся ли они в памяти или вычисляются или что-то ещё.

В этом смысле функциональное программирование сильно отличается от объектно-ориентированного программирования, потому что вы не инкапсулируете хранилище вместе с методами, определяющими функциональность, в этом хранилище. В функциональном программировании вы просто говорите о функциональности и описываете хранилище, которое может существовать, но на самом деле вы не реализуете его (not implementing).

Когда вы говорите, что у вас есть структура данных struct, которая “ведет себя” как что-то,  в нашем случае “ведет себя” как View, а мы поговорим о View через минуту, то мы действительно получаем обоюдоострый меч.

Одна сторона меча — действительно замечательная, потому что у View есть много функций, они встроены в библиотеку SwiftUI. Как только вы скажете, что “ведешь себя” как View, вы получаете всю эту функциональность, потому что Views делают все эти UI вещи, и вы, как один из этих View, сможете “вести себя” так же, что просто замечательно.

Другим краем обоюдоострого меча является то, что у вас появляются некоторые обязанности, если вы хотите “вести себя” как View. Вы не можете просто пройтись по улице и сказать: “Да, я “веду себя” как View.” Иногда “поведение” как View означает, что ты тоже должен кое-что сделать. Фактически,“поведение” как View, хотя это очень мощно, в действительности требует от тебя сделать всего лишь одну вещь, то есть иметь иметь эту переменную var body: some View:

Через мгновение мы собираемся рассмотреть эту переменную var body и понять, что это значит. Но сначала давайте поговорим о том, что такое View. Когда мы говорим, что эта структура данных struct, которую мы создаем, “ведет себя” как View, что это значит?

Что ж, View — это просто прямоугольная область на экране. Эта структура struct ContentView:View  — это большая прямоугольная область. Здесь углы закруглены, просто потому что устройство округляет их.

Структура struct ContentView: View представляет большую прямоугольную область и имеет возможность отображать другие вещи внутри себя. Здесь мы видим, что View отображает некоторый текст. Это хорошо. Но View также может получать входную информацию от пользователя в виде таких мультитач-событий или жестов, как tap (постукивание), swipe (смахивания), pinch (сведение и разведения пальцев) и другие подобные вещи.

Это все, что есть у View на самом деле. Это просто способ ввода и вывод в прямоугольную область на экране. Концепция простая, но в реализации это выглядит супер мощно, потому что мы хотим создавать очень красивые прямоугольные области на экране. Как, например, такие, где все переворачивается.

В таком виде у нас есть большая прямоугольная область в виде этого ContentView — это View верхнего уровня, но есть также и маленькие ViewНапример, маленький текст “New Game” (“Новая игра”) — это View, есть карточка — это тоже View, и на ней много других разных вещей. У карточки есть эмоджи (смайлик), обрамляющий прямоугольник с закругленными краями.

Если посмотреть на более сложную вещь, наш экран с выбором темы для игры, то он весь состоит из View меньшего размера, которые представляют собой многочисленные тексты, есть эта маленькая стрелка справа, которую можно кликнуть и перейти на другое View.

Все это —  View, любая прямоугольная область на экране является View. Вы видите, что некоторые View, похожие на эти карточки, встроены в более крупные View. То есть одни Views находятся внутри других Views. Это вроде очевидно, что почти каждая UI система имеет в основе идею, что на экране есть прямоугольные области и вы комбинируете их, чтобы создать свой UI.

Но в Swift мы делаем это с помощью дизайн-модели функционального программирования и говорим, что создаем этот ContentView, который “ведет себя” как View.

Что может делать View? Очень много всего. На самом деле мы уже видели, что может сделать View, когда использовали Отступы (Padding), для нашего текста «Hello, world!» ( «Привет, мир!»). Если мы кликнем в инспекторе Inspector в разделе Отступы (Padding), небольшой кружочек и посмотрим на код, то увидим там .padding():

А в панеле предварительного просмотра Preview отступы вокруг нашего приветствия  «Hello, world!» ( «Привет, мир!») немного увеличатся. Это всего лишь одна мелочь. Посмотрите на все эти другие вещи, представленные в инспекторе Inspector. Здесь показано, что можно делать с View: устанавливать цвет, шифр текста и т.д.

Мы собираемся увидеть это позже, когда будем использовать рычаги “поведения” View.

Но сначала я хотел бы рассмотреть оборотную сторону View, то есть каким требованиям мы должны удовлетворить, если мы хотим, чтобы наша структура struct “вела себя” как View. Мы должны реализовать переменную var body: some View :

И это отличная возможность говорить о переменных var внутри структуры данных struct в Swift. Вот как выглядит объявление переменной, супер просто. У вас есть ключевое слово var для переменной body — это просто имя этой переменной, затем следует двоеточие  : и some View — это другое, чем просто View при объявлении структуры struct, это ТИП этой переменной.

Это довольно сложный ТИП, но не столько сложный, сколько очень важный ТИП переменной и немного необычный. Обычно ТИПЫ бывают очень понятными. Например, переменная var i: Int — это целая переменная, переменная var s: String — это строка.

 

Вот на что обычно похожи большинство переменных в Swift. А у нас присутствует это странное ключевое слово some, оно выделено пурпурным цветом. Кроме того, у этого ТИПа есть View, а мы знаем, что это “поведенческая” вещь.

Итак, почему ТИП этой переменной var body имеет ТИП some View “поведенческую” вещь? ТИП some View в точности означает то, как это читается. Переменная var body это что-то, что “ведет себя” как ViewВот что такое переменная var body.

Давай подумаем об этом. Это как-то странно. Для того, чтобы создать структуру данных struct, которая “ведет себя” как View, нужно создать переменную var, чей ТИП представляет собой некоторую другую вещь some View, которая ведет себя как View. Это как-то странно.

Есть аналогия, которая поможет понять нам смысл, почему для того, что “вести себя” как View, у нас должна быть переменная, обеспечивающая нам кое-что другое, что “ведет себя” как View. И такой аналогией является Lego (Лего). Надеюсь, каждый из вас имел удовольствие играть в Lego (Лего).

Lego (Лего) — маленькие строительные блоки, которые вы используете для создания действительно крутых вещей, например, крошечного домика Lego (Лего). Вы можете построить «Звёздный эсминец« (Star Destroyer) в вымышленной вселенной «Звёздных войн». Lego (Лего) — это очень мощные маленькие строительные инструменты.

Если вы будете думать  о Views  по аналогии с Lego (Лего), то это не идеально, но вроде работает.

Давайте подумаем о Lego (Лего). Допустим, я хочу построить дом из Lego (Лего). В доме Lego (Лего) имеются комнаты. Есть кухня. Там есть спальни. Есть ванные комнаты. Допустим, там есть столовая. В каждом из них есть много других маленьких суб-Лего. На кухне куча кухонных шкафов,  стол и техника. В столовой есть обеденный стол и стулья. Вы видите, что домик Lego (Лего) на самом деле мы строим из других Lego (Лего). Мы можем думать об этом доме из Lego (Лего) просто  как о тысячах деталей Lego (Лего).

Когда мы действительно строим что-нибудь подобное домику Lego (Лего), то мы строим, скажем, столовую, мы строим маленький стол для столовой из какого-то Lego (Лего), а затем строим один стул для столовой из Lego (Лего). Затем собираемся построить еще один стул для столовой, и еще  один точно такой же стул для столовой. Мы могли бы, я не знаю, расставить восемь стульев для столовой вокруг нашего обеденного стола, и они все были бы точно такими же стульями для столовой.

Поэтому если мы подумаем о столовой и стуле в общем плане только как о Lego (Лего), то да, это Lego (Лего), построенное из других Lego (Лего) путем их комбинирования друг с  другом, но как только мы соединили все вместе, то, по сути, просто стул стал стулом для нашей столовой Lego (Лего).

Тогда мы можем взять восемь из них и объединить их с обеденным столом Lego (Лего), и теперь мы, по сути, имеем столовый набор Lego (Лего). Мы объединим это и с остальной мебелью в столовой, и у нас получится столовая Lego (Лего),  потом мы соединим вместе столовую Lego (Лего) с кухней Lego (Лего) и спальнями Lego (Лего) и ванной Lego (Лего). Мы соединяем их все вместе, и теперь у нас есть домик Lego (Лего). Мы можем поставить весь этот огромный дом Lego (Лего) вместе с другим домом Lego (Лего) и сделать район Lego (Лего), планету Lego (Лего), Вселенную Lego (Лего).

Мы могли бы построить целую Вселенная из Lego (Лего).

Если вы думаете таким образом и признаете, столовый стул Lego (Лего) есть сам по себе Lego (Лего), но построенный из ДРУГОГО Lego (Лего), то вы делаете большой скачок в понимании того, как создаются Views. Это имеет смысл потому, что если вы собираетесь “вести себя” как View, вы должны предоставить эту переменную var body: some View как какой-то ДРУГОЙ View.

Потому что мы будем создавать Lego (Лего) из Lego (Лего). Это так просто.

Чтобы понять нашу аналогию с Lego (Лего) немного лучше, давай поговорим немного о различных видах Views, которые вы найдете в SwiftUI. Конечно, вы найдете там такой View, как текст Text, который похож на кирпичик Lego (Лего), базовый строительный блок, существующий сам по себе.

Если мы посмотрим на наш UI, эти “кирпичики” повсюду.

На карте этот смайлик — это просто строка, немного текста. Так что это одна понятная разновидность View. Точно так же на экране справа у нас есть такие геометрические фигуры Shape как прямоугольник с закругленными углами, круг, овал, и тому подобное. Эти основные геометрические формы Shape также являются “кирпичиками” нашего Lego (Лего).

Но настоящие мощные View, которые мы собираемся найти в SwiftUI, это Viewобъединители (View combiners) Lego (Лего).

Viewобъединители (View combiners) — это то, что принимает другие Views и объединяет их на экране, либо расположив их в виде сетки, так показано на экране справа, либо просто расположив в линию, либо наложив один поверх другого и тому подобное.

Эти Viewобъединители (View combiners), наверное, самая важная вещь при создания сложных пользовательские интерфейсы UI в способности Lego (Лего) собирать собирать вещи по кусочкам.

Я собираюсь поговорить о еще одном вид View, который похож, если продолжать использовать аналогию Lego (Лего), «сумку» из Lego (Лего). Если вы покупаете очень большой набор Lego (Лего), в котором есть тысячи деталей, скажем, «Сокол тысячелетия» из «Звездных войн» или что-то в этом роде, то, когда вы открываете коробку, то видите, что сотрудники Lego очень любезно сгруппированы эти многие тысячи деталей в маленькие прозрачные пластиковые пакетики так, что когда вам нужно у «Сокола тысячелетия» построить только орудийную башню внизу или что-то в этом роде, то вам не нужно искать среди многих тысяч деталей искать те части, которые относятся к этой орудийной башне. Все эти детали для орудийной башни находятся в отдельном «пакетике». Вы открываете этот «пакетик», и там находится только пара сотен деталей для построения этой части  «Сокола тысячелетия».

Но вы не строите свой «Сокола тысячелетия» из Lego (Лего), просто бросив на него пакетик с орудийной башней или втыкаете это «пакетик» куда-то. Вы открываете «пакетик» и комбинируйте детали Lego (Лего) для построения орудийной башни Lego (Лего).

Итак, последние два вида Views, о которых я говорил, это View-объединители (View combiner) и «пакетик» Lego (Лего), они идут вместе. View-объединитель (View combiner) , очевидно, собирается взять пакетик Lego (Лего), открыть его и собрать все детали вместе.

Вооруженные этими знаниями относительно различных видов Views, вы видите, что переменная var body: some View почти всегда будет View-объединителем (View combiner). В нашем конкретном случае это всего лишь один “кирпичик” Lego (Лего), этот текст Text(«Hello, world!»), но some View в подавляющем большинстве будут View — объединителями (View combiner).

Мы вернемся к синтаксису some View через секунду и поймем, что на самом деле это означает.

Вторую часть Лекции 1 можно посмотреть здесь.