Включить представления SwiftUI в существующее приложение UIKit - PullRequest
15 голосов
/ 03 июня 2019

Можно ли строить представления с SwiftUI рядом с существующим приложением UIKit?

У меня есть существующее приложение, написанное на Objective-C.Я начал переход на Swift 5. Мне интересно, могу ли я использовать SwiftUI вместе с моими существующими представлениями UIKit .xib.

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

SomeObjCSwiftProject/
    SwiftUIViewController.swift
    SwiftUIView.xib
    UIKitViewController.swift
    UIKitView.xib

Работая рядом друг с другом

Ответы [ 4 ]

13 голосов
/ 03 июня 2019

edit 05/06/19: Добавлена ​​информация о UIHostingController, предложенная @Departamento B в его ответе.Кредиты идут к нему!


Использование SwiftUI с UIKit

Можно использовать SwiftUI компонентов в существующих UIKit средах, оборачивая SwiftUI View вUIHostingController вот так:

let swiftUIView = SomeSwiftUIView() // swiftUIView is View
let viewCtrl = UIHostingController(rootView: swiftUIView)

Также возможно переопределить UIHostingController и настроить его под свои нужды, например, установив preferredStatusBarStyle вручную, если он не работает через SwiftUI, какожидается.

UIHostingController задокументировано здесь .


Использование UIKit с SwiftUI

Если следует использовать существующее представление UIKitв среде SwiftUI протокол UIViewRepresentable поможет!Он задокументирован здесь и может быть замечен в действии в этом официальном руководстве Apple.


Совместимость

Обратите внимание, что компоненты UIKit и SwiftUI могут использоваться только совместно, если приложение предназначено для iOS 13+, поскольку SwiftUI доступна только для iOS 13+.См. этот пост для получения дополнительной информации.

7 голосов
/ 05 июня 2019

UIHostingController

Хотя на данный момент документация для класса не написана, UIHostingController<Content>, кажется, то, что вы ищете: https://developer.apple.com/documentation/swiftui/uihostingcontroller

Я простопопробовал это в моем приложении со следующей строкой кода:

let vc = UIHostingController(rootView: BenefitsSwiftUIView())

Где BenefitsSwiftUIView это просто «Hello World» по умолчанию View из SwiftUI.Это работает именно так, как вы ожидаете.Это также работает, если вы подкласс UIHostingController.

1 голос
/ 04 июня 2019

Вы можете использовать их вместе. Вы можете «передать» UIView в View с помощью 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 +
0 голосов
/ 21 июня 2019
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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...