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

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

UIViewRepresentable

SwiftUI предоставляет протокол специально для включения экземпляров UIView в ваш код. По сути, мы собираемся создать структуру View, которая возвращает класс UIView.
Протокол UIViewRepresentable наследуется от View. Однако он указывает, что это View, который не реализует вычисляемое свойство body. Итак, это представление, но не такое, как мы видели раньше.
Вместо этого протокол определяет функцию, которая должна быть реализована. Функция makeUIView для классов UIKit в SwiftUI должна возвращать UIView. Просто.
Он также передается в контексте для любых значений, которые вам может понадобиться получить.
Когда состояние меняется и пора обновить пользовательский интерфейс, появляется другая функция: updateUIView. Эта функция вызывается при изменении каких-либо привязок. В коде функции вы обновите пользовательский интерфейс программно на основе изменений.
При желании вы можете реализовать демонтажUIView. Это вызывается при очистке памяти. Если вам нужно выполнить какие-либо действия в последний момент, когда UIView удаляется, это ваш шанс.
Вместо отображения текста заметки при нажатии на строку мы отобразим детали заметки.
Если вы работаете с macOS, аналогичный протокол - NSViewRepresentable. Точно так же представления WatchKit можно использовать с WKInterfaceObjectRepresentable.

NoteView имеет свойство привязки для NoteViewModel. Он используется в теле для отображения деталей. VStack содержит текстовые элементы для обновляемых данных, текст заметки и элемент Image для связанного изображения.
Код предварительного просмотра загружает тестовые данные и отображает элемент

Извлечение представления

Одна вещь, отсутствующая в деталях нашей заметки, - это приоритет. Конечно, было бы неплохо иметь это. Но было бы лучше, если бы мы могли повторно использовать уже написанный код.
Мы можем сделать это, извлекая эту часть NoteRow в ее собственную структуру View. В NoteRow у нас есть HStack, который включает изображения звездочек приоритета и обновляемые по времени. Щелкните HStack, чтобы получить дополнительную информацию (см. Рисунок 3).

Мы хотим извлечь представление, и для этого есть пункт меню. Если мы щелкнем этот элемент, он извлечет код и позволит нам установить имя для новой структуры представления. Я назову свое NotePriorityAndTime.
Однако у нас есть ошибка компиляции, так как наше новое представление не имеет доступа к значению noteVM. Без проблем. Мы можем добавить это свойство в представление и вызвать его создание.

Не забудьте обновить создание с новым параметром noteVM обратно в VStack NoteRow.

NotePriorityAndTime (noteVM: noteVM)

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

В NoteView заменим текущий код HStack.

HStack {
Spacer ()
Текст («Обновлено в: \ (noteVM.time)»)
}

Мы можем заменить весь HStack новым представлением, которое мы создали.
NotePriorityAndTime (noteVM: noteVM)
Там, где раньше было время, теперь у нас есть приоритет и время с использованием цвета рендеринга

Это может быть хорошо для отображения деталей, но не очень хорошо. И это не позволяет редактировать заметку. Для этого нам нужно вернуться к UIViewRepresentable и использовать UITextView для нашей заметки. Однако имейте в виду, что он доступен для iOS 14.