Найти тему

Как реализовать Live Preview в проекте на UIKit

Всем привет! Вы на канале школы мобильной разработки SwiftBook. Здесь мы рассказываем и показываем всё, что знаем о языке Swift и Kotlin: увлечённо, понятно и без воды.

С вами Анна Васичко и сегодня я покажу вам один полезный и удобный способ работы в UIKit, про который вы, возможно, не знали.

Ссылка на видео здесь.

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

Для этого я создам проект с интерфейсом Storyboard и перейду в файл ViewController.

Здесь мы импортируем фреймворк SwiftUI и объявим структуру ViewControllerPreview, подписанную под протокол UIViewControllerRepresentable

Эта структура при обращении к ней будет принимать замыкание с типом вью контроллера.

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

-2

Помимо этого мы реализуем два метода, которые требует протокол.

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

struct ViewControllerPreview: UIViewControllerRepresentable {

let viewControllerGenerator: () -> UIViewController

init(viewControllerGenerator: @escaping () -> UIViewController) {

self.viewControllerGenerator = viewControllerGenerator

}

func makeUIViewController(context: Context) -> some UIViewController {

viewControllerGenerator()

}

func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {

}

}

Теперь во viewDidLoad мы поменяем цвет фона на, например, оранжевый.

Внизу под классом объявим ещё одну структуру ViewControllerProvider, подписанную под PreviewProvider для отображения превью.

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

Также через точку вызовем здесь метод для того, чтобы не отображать safe area:

struct ViewControllerProvider: PreviewProvider {

static var previews: some View {

ViewControllerPreview {

ViewController()

}.edgesIgnoringSafeArea(.all)

}

}

Включим режим canvas и увидим превью нашего вью контроллера.

-3

Добавим в него лэйбл

let helloLabel: UILabel = {

let label = UILabel()

label.text = "Hello World"

label.textColor = .white

label.font = .systemFont(ofSize: 30, weight: .semibold)

return label

}()

И метод по настройке констрейнтов:

private func setupConstraints() {

view.addSubview(helloLabel)

helloLabel.translatesAutoresizingMaskIntoConstraints = false

NSLayoutConstraint.activate([

helloLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),

helloLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor)

])

}

Вызовем метод во viewDidLoad и увидим все изменения в превью.

Можем поменять цвет фона и также увидеть изменения.

-4

Теперь предлагаю вынести структуру для генерации превью в расширение

Добавляем файл UiViewController + Extension

Импортируем здесь SwiftUI.

Делаем расширение к вью контроллера и копируем сюда структуру из файла вью контроллер, сделаем теперь её приватной и поменяем название на просто Preview.

Внутри мы объявим свойство с типом вьюконтроллера, инициализатор убегающего замыкания нам больше не нужен, в методе вернём вью контроллер

И также в расширении добавим метод по отображению превью

Внутри будем инициализировать структуру вью контроллером и вызывать также функцию для игнорирования safe area extension UIViewController {

private struct Preview: UIViewControllerRepresentable {

let viewController: UIViewController

func makeUIViewController(context: Context) -> some UIViewController {

viewController

}

func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {

}

}

func showPreview() -> some View {

Preview(viewController: self).edgesIgnoringSafeArea(.all)

}

}

Теперь вернёмся в файл с вью контроллером, удалим отсюда структуру, а в структуре провайдере внутри вычисляемого свойства обратимся к самому вью контролеру и вызовем у него метод shoPreview

И всё будет работать также.

Но при такой организации кода нам теперь будет доступно вызывать этот метод для всех UIViewController в нашем приложении.

-5

На этом у меня всё, надеюсь, это видео было для вас полезным, спасибо за внимание!

Подписывайся на наши соцсети: Telegram / VKontakte
Вступай в открытый чат для iOS-разработчиков: t.me/swiftbook_chat