在 UIKit 中使用 Swift UI

2021-12-28 10:59:07 浏览数 (1)

本文基于 Xcode 12.3 Swfit 5.3.2 iOS 14.3 macOS 11.2 构建

无意间发现好像不止可以在 Swift UI 中用上 UIKit,反过来亦然。

首先打开 Xcode 新建一个 Cocoa Touch 项目,interface 选择 Storyboard。

随后,新建一个 Swift UI File,命名为 ContentView.swift。文件会自动生成一个 ContentView 的 Swift UI View。

接下来需要把 Swift UI View 用在 UIKit 中,需要用到 Swift UI 中的

UIHostingController

。这是可以把 Swift UI 包装成 UIView。

在 Main.stroyboard 中将 rootViewController 包装上一个 NavigtaionController,不用多说了。之后打开 ViewController.swift。在 viewDidLoad 中加上如下代码:

swift

代码语言:javascript复制
1let uiButton = UIButton(type: .system)
2
3uiButton.setTitle("Button", for: .normal)
4uiButton.translatesAutoresizingMaskIntoConstraints = false
5uiButton.addTarget(self, action: #selector(click), for: .touchUpInside)
6
7view.addSubview(uiButton)
8
9uiButton.snp.makeConstraints { make in
10    make.center.equalTo(view)
11}

COPY

方便起见,以上代码使用了 SnapKit,在运行之前请先下载安装

SnapKit

在再底下加个方法

swift

代码语言:javascript复制
1@objc func click() {
2    let vc = UIHostingController(rootView: ContentView())
3
4    navigationController?.pushViewController(vc, animated: true)
5}

COPY

OK, 现在可以 Run 了。点击中央的 Button 之后将会 Push 到一个由 Swift UI 构建的 View。

接下来,如果不用 PushViewController 的方式把 Swift UI View 直接挂载到 RootViewController。

将 ViewController 中 viewDidLoad 中代码替换成

swift

代码语言:javascript复制
1super.viewDidLoad()
2let hostVc = UIHostingController(rootView: ContentView())
3view.backgroundColor = .systemBackground
4let sview = hostVc.view as! UIView
5
6view.addSubview(sview)
7sview.snp.makeConstraints({ make in
8    make.bottom.equalTo(view)
9    make.top.equalTo(view)
10    make.left.equalTo(view)
11    make.right.equalTo(view)
12    make.width.equalTo(view)
13    make.height.equalTo(view)
14})

COPY

然后我又发现了点好玩的东西。如何在 Swift UI 直接用上 UINavigationController 和 UITabBarController。

Innei/SwiftUI-in-UIKit-with-UINavtigationController-test

https://twitter.com/__oquery/status/1358376605995868162?s=21

刺激。

NavigationController 外置的另一方式

如下写法能让 SwiftUI 内部识别到外层 UINavigationController,无需包裹 NavigationView 即可使用 NavigationLink,同时还能使用 UINavigationController 更完善的方法。

swift

代码语言:javascript复制
1var hv = UIHostingController(rootView: TestView())
2var myNavigationController = UINavigationController(rootViewController: hv)
3
4struct TestView: View {
5    var body: some View {
6        Form {
7            NavigationLink("Navigation", destination: EmptyView())
8        }.navigationTitle("Test")
9    }
10}
11
12class ViewController: UIViewController {
13    override func viewDidLoad() {
14        super.viewDidLoad()
15    }
16}
17      

0 人点赞