Подходы к реализации UI в Swift

Dmitriy Putkov
6 min readApr 24, 2020

--

Всем привет, меня зовут Дима, и я iOS-разработчик 👨🏻‍💻. Сегодня хотел поделиться способами реализации UI в iOS.

Дело в том, что во всех проектах, в разработке которых я принимал участие, UI создавался по-разному. И это при том, что вариантов всего три: Xib, Storyboards и кодинг 😅 Давайте разберемся, в чем их основные особенности. Для начала, я опишу каждый из инструментов:

XIB:

XIB расшифровывается как XML Interface Builder. Такие файлы внутри себя хранят вью, лейауты и значения, описанные на xml. По сути своей это иерархический набор описаний объектов. Такой XIB файл компилируется в бинарный Nib файл. Nib файл, соответственно, уже нельзя открыть в Interface Builder. Именно он будет включен в ваше собранное приложение в том виде, в котором он скомпилировался из XIB. Это, кстати, причина, почему, когда вы вызываете в коде инстанс View, описанной на XIBах, вы обращаетесь к NIB.

Storyboard:

Это, как предлагает Apple, post-XIB, по сути, более удобный способ программирования UI в IB. Под капотом у него все тот же xml с той же компиляцией в nib файлы. Однако, на сторибордах отображается представление UI через показ экранов( а не одного элемента, который можно было сделать в XIB), контента этих экранов и, что мне больше всего импонирует, возможность визуализации флоу пользовательского сценария. Особенно на проектах, где аналитика описана через диаграммы взаимодействия с экранами, одно удовольствие перенести это на флоу в сториборды и разбить по юзкейсам.

Code

Программирование UI элементов через код, соответственно без компиляции в nib, а напрямую в .o файлы, людям, которые до этого создавали UI через графические инспекторы, кажется сложнее, чем перетаскивание квадратиков, но, набив руку, это становится очень увлекательным занятием, в котором сразу же подсвечивается огромное количество плюсов (о них позже). Пока выделим два момента:
1. Все, что можно создать через графические интерфейсы, можно создать в коде, наоборот не работает :)
2. Переиспользование юай элементов становится намного проще.

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

XIB

что хорошо:

  1. Немедленное отображение результата — Я думаю, вы со мной согласитесь, что программировать UI проще, когда можно сразу же увидеть складывающуюся картинку.
  2. Подсвечивание атрибутов UI элемента — В IB есть замечательный Attributes Inspector, который подсвечивает нам основные поля для конфигурации. Удобно, тем более что в связке с первым пунктом дает понимание, как тот или иной атрибут влияет на View в целом 🤤
  3. Жесткий контроль за S в SOLID — в XIB можно максимально полно описать только один элемент, удобно при переиспользовании этого элемента в нескольких местах в проекте.

где болит:

  1. Это XML-файл, который даже при открытии без изменений в любой системе контроля версий может отобразиться как файл с изменениями. Это очень больно на проектах, в которых 2 и больше человек принимают участие.
  2. Невозможность изменять атрибуты элементов и констрейнты в рантайме — однажды скомпилировавшись в NIB, мы не можем поменять его значение без явного вмешательства в коде. Кстати поэтому динамически изменяемые вью не получится реализовывать через XIB.
  3. В списке атрибутов не подсвечены все возможные атрибуты, в частности layer, благодаря которому можно создавать тени, закругления, анимации. Про то, как решить эту проблему, я писал небольшую статью.
  4. Как ни странно, но третий минус в списке — это немасштабирование третьего в списке плюса: мы, к сожалению, имеем возможность полноценно создать только одну вью, вместо кластера вью, относящихся к одному экрану. Да, мы можем создать в IB несколько элементов, но использование функционала File’s Owner будет доступно только одному, что во многом ограничивает возможности других.

Storyboard

что хорошо:

Первые два пункта для XIB в равной степени применимы и для Storyboard, Поэтому продублируем:

  1. Подсвечивание атрибутов UI элемента
  2. Немедленное отображение результата
  3. Намного более широкие возможности конфигурации — Можно описать флоу навигации по экранам, переходы между экранами.
  4. Очень удобно переносить юзкейсы и сценарии использования, описанные в сервисах по типу Miro на сториборды.
слева — бизнес-флоу на Miro, справа — реализация в storyboard

где болит:

Аналогично, первые три пункта из XIB применимы и для Storyboad:

  1. Проблемы с CVS
  2. Невозможность изменять атрибуты элементов и констрейнты в рантайме
  3. В Attributes Inspector не подсвечены все возможные атрибуты
  4. Нельзя создавать отдельные UI элементы без отношения к ViewController — это неприятно, потому что затрудняет переиспользование элементов
  5. Data flow — хоть в Storyboards уже можно описывать навигацию и даже анимацию при переходах, дата флоу описать с его помощью не получится, а во многих случаях переход между экранами напрямую связан и с передачей данных.

Code

что хорошо:

  1. Время компиляции уменьшится за счет того, что компилятору не придется компилировать xml — вы выиграете во времени, что сэкономит приличное количество времени на больших проектах.
  2. UI станет по-настоящему reusable, причем его переиспользуемость может масштабироваться от лейбла до всего экрана.
  3. Конфигурация атрибутов UI элементов будет находиться в одном месте: для сложных UI-элементов, при создании их в IB, вам так или иначе придется писать код. Теперь задание атрибутов элементов будет только в коде. Круто же ?🕺
  4. Отсутствие конфликтов «по-причине-просто-так» один из ключевых плюсов.
  5. Кстати, если говорить про работу с системой контроля версий, то тут стоит еще сказать об облегчении ревью: для того, чтобы посмотреть реализацию UI не нужно переходить на ветку, и смотреть в IB — все заканчивается на этапе чтения кода.
  6. SwiftUI: предложенный Apple в конце 2019 подход к созданию приложений опирается на описание UI декларативным стилем программирования, быстро, легко и понятно. Там даже есть реал-тайм перевод из IB в код!

где болит:

  1. Очевидно, это отсутствие видимых изменений «в моменте», что увеличивает время создания UI элементов.
  2. Реально много кода: чтобы задать только одной вью 4 констрейнта, потребуется минимум 5 строчек. Если учесть, что у вью, помимо этого, есть и кастомизация атрибутов( в среднем 3–6 строчек), и при условии, что таких вью на экране будет много, это превращается в достаточно большой холст.
  3. При некорректной расстановке констрейнтов или их приоритетов, IB подсветит их красным и подскажет, каких констрейнтов не хватает. При кодинг подходе вы узнаете об этом только на этапе рантайма.
  4. Достаточно тяжеловесная работа с констрейнтами — для оптимизации необходимо придерживаться многих правил. Часто для этого прибегают к third-party библиотекам, которые уже реализовали это. В таком случае возникает зависимость от сторонних библиотек, что тоже не совсем хорошо. Напротив, IB вам сам расставит необходимые констрейнты, если вы его попросите, и проведет нужные оптимизации.

Фуух, вроде все описали. Осталось раскрыть основную цель статьи: что и когда использовать. Я бы предложил следующее разбиение:

  • Если в команде разработчиков большое число человек, а задачи сильно связаны между собой, я считаю использование кода для UI наилучшим вариантом. Вы избежите проблем с конфликтами, вы всегда можете работать над одной UI задачей вместе, а проект будет компилироваться быстрее.
  • При разработке проекта в команде до 3х человек или при грамотной декомпозиции задач можно комфортно использовать IB. Также я бы порекомендовал этот подход при сложной навигации в проекте — таким образом введение в проект новых людей будет происходить быстрее, да и в целом картинка перед глазами всегда приятна.

    Учтите, что при выборе в пользу IB, вам все равно не избежать реализации некоторых моментов в коде. Также, даже если вы преимущественно работаете на storyboard, многие вещи можно вынести в xib, а затем переиспользовать в конфигурации экранов. Это уменьшит время компиляции и позволит поддерживать код в чистоте. Я попробовал оптимизировать подобный смешанный подход, результатом чего стала статья Make UI development easier in iOS

Всем удачи, пишите мне в twitter @PutkovD, если появились вопросы, буду рад на них ответить :)

--

--