Включить представления SwiftUI в существующее приложение UIKit
Возможно ли строить представления с SwiftUI рядом с существующим приложением UIKit?
У меня есть приложение, написанное на Objective-C. Я начал миграцию на Swift 5. Мне интересно, могу ли я использовать SwiftUI вместе с моими существующими представлениями UIKit.xib.
То есть я хочу, чтобы некоторые представления, созданные с помощью SwiftUI, и некоторые другие представления, созданные с помощью UIKit в том же приложении. Не смешивая два, конечно.
SomeObjCSwiftProject/
SwiftUIViewController.swift
SwiftUIView.xib
UIKitViewController.swift
UIKitView.xib
Работать рядом друг с другом
Ответы
Ответ 1
редактировать 06.05.19: Добавлена информация о UIHostingController, предложенная @Departamento B в его ответе. Кредиты идут к нему!
Использование SwiftUI с UIKit
Можно использовать SwiftUI
компоненты в существующих UIKit
сред обертывания SwiftUI
View
в UIHostingController
, как это:
let swiftUIView = SomeSwiftUIView() // swiftUIView is View
let viewCtrl = UIHostingController(rootView: swiftUIView)
Также возможно переопределить UIHostingController
и настроить его в соответствии с UIHostingController
потребностями, например, установив вручную preferredStatusBarStyle
SwiftUI
если он не работает через SwiftUI
как ожидалось.
UIHostingController
здесь.
Использование UIKit с SwiftUI
Если существующий UIKit
вид следует использовать в SwiftUI
среде, UIViewRepresentable
протокол, чтобы помочь! Это задокументировано здесь, и его можно увидеть в действии в этом официальном руководстве Apple.
Совместимость
Обратите внимание, что компоненты UIKit
и SwiftUI
могут использоваться только в сочетании, если приложение предназначено для iOS 13+, поскольку SwiftUI
доступен только для iOS 13+. Смотрите этот пост для получения дополнительной информации.
Ответ 2
UIHostingController
Хотя на данный момент документация для этого класса еще не написана, UIHostingController<Content>
кажется, является тем, что вы ищете: https://developer.apple.com/documentation/swiftui/uihostingcontroller
Я только что попробовал это в моем приложении со следующей строкой кода:
let vc = UIHostingController(rootView: BenefitsSwiftUIView())
Где BenefitsSwiftUIView
просто по умолчанию "Hello World" View
из SwiftUI
. Это работает именно так, как вы ожидаете. Это также работает, если вы подкласс UIHostingController
.
Ответ 3
Вы можете использовать их вместе. Вы можете "передать" UIView
в View
с UIViewRepresentable
соответствия UIViewRepresentable
. Подробности можно найти в официальном учебнике.
Тем не менее, вы также должны учитывать его совместимость.
Вот фрагмент кода из протокола View
SwiftUI:
///
/// You create custom views by declaring types that conform to the 'View'
/// protocol. Implement the required 'body' property to provide the content
/// and behavior for your custom view.
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public protocol View : _View {
/// The type of view representing the body of this view.
///
/// When you create a custom view, Swift infers this type from your
/// implementation of the required 'body' property.
/// ...
}
Так что это не обратно совместимо.
- iOS 13. 0+
- macOS 10. 15+
- watchOS 6. 0+
Ответ 4
Старый проект:
Вы не можете использовать swiftUI и UIKit вместе.
Ссылайтесь на официальные документы Apple
Бета-версия Xcode 11 не поддерживает работу с SwiftUI в проекте, настроенном для использования UIKit для Mac.
Новый проект:
Да, может сделать это.
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public protocol View : _View {
}
SwiftUI не имеет обратной совместимости, поэтому ваша цель развертывания должна быть> = 13.0
Ответ 5
import Foundation
#if canImport(SwiftUI)
import SwiftUI
internal final class SomeRouter {
fileprivate weak var presentingViewController: UIViewController!
function navigateToSwiftUIView() {
if #available(iOS 13, *) {
let hostingController = UIHostingController(rootView: contentView())
presentingViewController?.navigationController?.pushViewController(hostingController, animated: true)
return
}
//Keep the old way when not 13.
}
#endif