В предыдущих статьях все представления были созданы на Storyboard с помощью визуального редактора. У этого подхода есть существенный недостаток - сложность переиспользования полученных представлений в других местах приложения. В данной статье мы рассмотрим другой подход создания представления - загрузка представлений из специальных файлов Xib(Nib), - который лишен указанного недостатка.
Xib(NIb) файлы используются для создания кастомных UI-элементов.
Для того, чтобы показать, как создать нужный вам UI-элемент, перейдем в проект Xcode.
Предположим, нам нужно переиспользовать представление панели канала. Панель канала - это элемент с информацией о канале, его описание, включающее в себя ряд элементов, таких как лейблы, картинка и кнопка.
Вынесем их в отдельную сущность. Создадим новый файл.
Также создадим одноименный Xib файл. Для этого выберем View в разделе User Interface.
В проекте появился файл ChannelHeaderView.xib. Сейчас он представляет собой пустое поле, размеры которого напоминают размеры устройства.
Откроем вкладку Attributes Inspector в правом вспомогательном окне Xcode и увидим на верхние свойства - Size, Top Bar и Bottom Bar. Они определяют, как выглядит данное представление в Interface Builder. К его размерам и наличию баров в запущенном приложении они не имеют никакого отношения. Настроим поле Size как нам удобно. А именно установим для него значение Freeform.
Так мы можем изменять размеры вручную. Уменьшим размеры полотна до реальных.
Теперь можно перенести элементы из библиотеки объектов на созданное кастомное вью и реализовать панель канала.
Данное представление состоит из горизонтального стека, состоящего из вертикального стека и картинки канала, лейбла описания канала и кнопки редактирования информации о канале. Вертикальный стек внутри горизонтального стека представляет из себя лейбл названия канала и горизонтальный стек с 3 лейблами, в которых отображается статистика о канале.
Для того, чтобы представление корректно отображалось на экране любого запущенного устройства, Xcode имеет специальный механизм - Auto Layout. Чтобы этот механизм мог определить расположение элементов вью на экране, были добавлены ограничения (привязки, constraints) к некоторым из них. Подробно об ограничениях речь пойдет в следующей статье.
Теперь реализуем следующую задачу: свяжем класс из файла ChannelHeaderView.swift и ксиб ChannelHeaderView.xib друг с другом.
Но перед этим давайте посмотрим на конструкторы UIView.
Класс некоторого представления типа UIView может быть инициализирован из Xib(Nib), Storyboard или программно.
При загрузке представления из Xib будут вызваны методы required init?(coder: NSCoder) и затем awakeFromNib().
При работе с ксибами их обычно загружают в коде специальной функцией loadNibNamed, а они уже создают объект класса, указанный в поле Custom Class для своей View (представления). Storyboard также создает указанный в Custom Class класс, но не умеет сперва загружать какой-либо ксиб. Поэтому для загрузки представления в данном случае нужно будет в загружаемом классе программно подгрузить представление из соответствующего ксиба.
При загрузке представления из кода вызывается метод init(frame: CGRect).
Пропишем загрузку ксиба в конструкторе загружаемого из сториборда класса.
Но сперва зададим поле Custom Class в ксибе. Для этого откроем файл ChannelHeaderView.xib. В окне Document outline в разделе Placeholders выбираем поле File’s Owner. В Identity Inspector указываем Custom Class - ChannelHeaderView.
Возвращаемся в класс ChannelHeaderView. Напишем функцию загрузки представления из ксиба.
Переопределим метод инициализации представления init?(coder: NSCoder), не забывая вызвать код superview-класса.
Внутри конструктора вызовем еще одну вспомогательную функцию configureView(). В этой функции мы получаем загруженную из ксиба вью и размещаем ее в иерархию текущего представления.
Далее добавим элемент UIView в сториборд на сцену. Из нее должно загрузиться наше представление.
Открываем файл Main.storyboard. Для начала удалим ранее размещенную на сцене кнопку Log Button. Разместим на сцене UIView. Для этого найдем в библиотеке объектов UIView и перетащим его на сцену.
И добавим привязки для нового элемента.
Перейдем в Identity Inspector в правом вспомогательном окне и в поле Class раздела Custom Class укажем реализованное ранее представление ChannelHeaderView.
Запустим приложение на симуляторах различных устройств.
Осталось сделать самую малость - заполнить элементы данными.
Свяжем элементы представления с кодом. Для создания доступа к графическому элементу из кода служит ключевое слово @IBOutlet.
Далее реализуем функцию, с помощью которой будем устанавливать данные в элементы представления. А также настроим дизайн экрана: скруглим картинку и укажем шрифты, - переопределив метод awakeFromNib().
Вызовем функцию setupView() при появлении контроллера на экране.
И посмотрим на получившийся результат.
В следующей части мы поговорим про механизм, который позволяет создавать адаптивный интерфейс на основе ограничений (constraints), Auto Layout.