Интеграция с фреймворком UIKit
Compose Multiplatform совместим с фреймворком UIKit. Вы можете встроить Compose Multiplatform в приложение UIKit, а также встроить нативные компоненты UIKit в Compose Multiplatform. На этой странице приведены примеры использования Compose Multiplatform в приложении UIKit и встраивания компонентов UIKit в интерфейс Compose Multiplatform.
Использование Compose Multiplatform в приложении UIKit
Чтобы использовать Compose Multiplatform в приложении UIKit, добавьте код Compose Multiplatform в любой контейнерный контроллер представления. В этом примере Compose Multiplatform используется внутри класса UITabBarController:
let composeViewController = Main_iosKt.ComposeOnly()
composeViewController.title = "Compose Multiplatform inside UIKit"
let anotherViewController = UIKitViewController()
anotherViewController.title = "UIKit"
// Set up the UITabBarController
let tabBarController = UITabBarController()
tabBarController.viewControllers = [
// Wrap the created ViewControllers in a UINavigationController to set titles
UINavigationController(rootViewController: composeViewController),
UINavigationController(rootViewController: anotherViewController)
]
tabBarController.tabBar.items?[0].title = "Compose"
tabBarController.tabBar.items?[1].title = "UIKit"
После выполнения этого кода приложение должно выглядеть так:

Изучите этот код в примере проекта.
Использование UIKit в Compose Multiplatform
Чтобы использовать элементы UIKit в Compose Multiplatform, добавьте нужные элементы UIKit в UIKitView из Compose Multiplatform. Этот код можно написать только на Kotlin или также использовать Swift.
Представление карты
Представление карты в Compose Multiplatform можно реализовать с помощью компонента MKMapView из UIKit. Задайте размер компонента с помощью функций Modifier.size() или Modifier.fillMaxSize() из Compose Multiplatform:
UIKitView(
factory = { MKMapView() },
modifier = Modifier.size(300.dp),
)
После выполнения этого кода приложение должно выглядеть так:

Теперь рассмотрим более сложный пример. Этот код оборачивает UITextField из UIKit в Compose Multiplatform:
@OptIn(ExperimentalForeignApi::class)
@Composable
fun UseUITextField(modifier: Modifier = Modifier) {
// Holds the state of the text in Compose
var message by remember { mutableStateOf("Hello, World!") }
UIKitView(
factory = {
// Creates a UITextField integrated with Compose state
val textField = object : UITextField(CGRectMake(0.0, 0.0, 0.0, 0.0)) {
@ObjCAction
fun editingChanged() {
// Updates the Compose state when text changes in UITextField
message = text ?: ""
}
}
// Adds a listener for text changes within the UITextField
textField.addTarget(
target = textField,
action = NSSelectorFromString(textField::editingChanged.name),
forControlEvents = UIControlEventEditingChanged
)
textField
},
modifier = modifier.fillMaxWidth().height(30.dp),
update = { textField ->
// Updates UITextField text from Compose state
textField.text = message
}
)
}
Параметр factory содержит функцию
editingChanged()и слушательtextField.addTarget()для обнаружения любых изменений вUITextField.Функция
editingChanged()аннотирована с помощью@ObjCAction, чтобы обеспечить совместимость с кодом Objective-C.Параметр
actionфункцииaddTarget()передаёт имя функцииeditingChanged(), вызывая её в ответ на событиеUIControlEventEditingChanged.Параметр
updateфункцииUIKitView()вызывается при изменении значения наблюдаемого состояния сообщения.Функция обновляет атрибут
textобъектаUITextField, чтобы пользователь видел обновлённое значение.
Изучите код этого примера в нашем примере проекта.
Представление камеры
Представление камеры в Compose Multiplatform можно реализовать с помощью компонентов UIKit AVCaptureSession и AVCaptureVideoPreviewLayer.
Это позволяет приложению получать доступ к камере устройства и показывать видео с неё в режиме реального времени.
Вот пример реализации простого представления камеры:
UIKitView(
factory = {
val session = AVCaptureSession().apply {
val device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)!!
val input = AVCaptureDeviceInput.deviceInputWithDevice(device, null)!!
addInput(input)
}
val previewLayer = AVCaptureVideoPreviewLayer(session)
session.startRunning()
object : UIView() {
override fun layoutSubviews() {
super.layoutSubviews()
previewLayer.frame = bounds
}
}.apply {
layer.addSublayer(previewLayer)
}
},
modifier = Modifier.size(300.dp)
)
Теперь рассмотрим более сложный пример. Этот код делает снимок, добавляет метаданные GPS и отображает изображение с камеры в режиме реального времени с помощью нативного UIView:
Компонуемый элемент RealDeviceCamera выполняет следующие задачи:
Настраивает нативный предпросмотр с камеры с помощью
AVCaptureSessionиAVCaptureVideoPreviewLayer.Создаёт
UIKitView, в котором размещается пользовательский подклассUIView, отвечающий за обновление макета и встраивание слоя предпросмотра.Инициализирует
AVCapturePhotoOutputи настраивает делегат для обработки съёмки.Использует
CLLocationManager(черезlocationManager), чтобы получить координаты GPS в момент съёмки.Преобразует полученное изображение в
UIImage, оборачивает его вPlatformStorableImageи передаёт метаданные, такие как имя, описание и местоположение GPS, с помощьюonCapture.Отображает круглую компонуемую кнопку для запуска съёмки.
Применяет настройки зеркального отображения при использовании фронтальной камеры, чтобы селфи выглядело привычно.
Динамически обновляет макет предпросмотра в
layoutSubviews()с помощьюCATransaction, чтобы избежать анимации.
Полный код этого примера можно посмотреть в примере проекта ImageViewer.
Веб-представление
Веб-представление в Compose Multiplatform можно реализовать с помощью компонента UIKit WKWebView. Это позволяет приложению отображать веб-контент и взаимодействовать с ним в интерфейсе. Задайте размер компонента с помощью функций Modifier.size() или Modifier.fillMaxSize() из Compose Multiplatform:
UIKitView(
factory = {
WKWebView().apply {
loadRequest(NSURLRequest(URL = NSURL(string = "https://www.jetbrains.com")))
}
},
modifier = Modifier.size(300.dp)
)
Теперь рассмотрим более сложный пример. Этот код настраивает веб-представление с делегатами навигации и обеспечивает взаимодействие между Kotlin и JavaScript:
@Composable
fun WebViewWithDelegate(
modifier: Modifier = Modifier,
initialUrl: String = "https://www.jetbrains.com",
onNavigationChange: (String) -> Unit = {}
) {
// Creates a delegate to listen for navigation events
val delegate = remember {
object : NSObject(), WKNavigationDelegateProtocol {
override fun webView(
webView: WKWebView,
didFinishNavigation: WKNavigation?
) {
// Updates the current URL after navigation is complete
onNavigationChange(webView.URL?.absoluteString ?: "")
}
}
}
UIKitView(
modifier = modifier,
factory = {
// Instantiates a WKWebView and sets its delegate
val webView = WKWebView().apply {
navigationDelegate = delegate
loadRequest(NSURLRequest(uRL = NSURL(string = initialUrl)))
}
webView
},
update = { webView ->
// Reloads the web page if the URL changes
if (webView.URL?.absoluteString != initialUrl) {
webView.loadRequest(NSURLRequest(uRL = NSURL(string = initialUrl)))
}
}
)
}
Компонуемый элемент WebViewWithDelegate выполняет следующие задачи:
Создаёт стабильный объект-делегат, реализующий интерфейс
WKNavigationDelegateProtocol. Этот объект сохраняется между рекомпозициями с помощьюrememberиз Compose.Создаёт экземпляр
WKWebView, встраивает его с помощьюUIKitViewи настраивает, назначая сохранённый делегат.Загружает начальную веб-страницу, указанную в параметре
initialUrl.Отслеживает изменения навигации через делегат и передаёт текущий URL через обратный вызов
onNavigationChange.Использует параметр
updateдля отслеживания изменений запрошенного URL и соответствующей перезагрузки веб-страницы.
Что дальше
Также вы можете узнать, как интегрировать Compose Multiplatform с фреймворком SwiftUI.
© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/multiplatform/compose-uikit-integration.html