介绍
混合开发主要是指在 SwiftUI 中使用 UIKit(SwiftUI 中使用 UIView 与 UIViewController)与在 UIKit 中使用 SwiftUI。通过混合开发,开发者可以更灵活地利用 SwiftUI 与 UIKit 的各自优势,开发出功能强大且具有良好用户体验的应用程序。
UIKit in SwiftUI
Apple 针对 UIView 与 UIViewController 提供了两个 “表示器”,如下表所示。通过这两个表示器可以很容易地将它们转换成 SwiftUI 里面的 View。
| UIKit | SwiftUI |
|---|---|
| UIView | UIViewRepresentable |
| UIViewController | UIViewControllerRepresentable |
UIView in SwiftUI
UIViewRepresentable
- 要使 UIView 在 SwiftUI 中可用,需要用
UIViewRepresentable对 UIView 进行包装。 UIViewRepresentable中主要有 2 个方法需要实现。makeUIView():创建View。updateUIView():根据条件与业务逻辑设置View的状态。
案例
使用 UIKit 中的UIActivityIndicatorView。
import SwiftUI
import UIKit
struct ActivityIndicator: UIViewRepresentable {
var isAnimating: Bool
// 如下的2个方法都是与UIKit相关
func makeUIView(context: Context) -> UIActivityIndicatorView {
let v = UIActivityIndicatorView()
v.color = .orange
return v
}
func updateUIView(_ uiView: UIActivityIndicatorView, context: Context) {
if isAnimating {
uiView.startAnimating()
} else {
uiView.stopAnimating()
}
}
}
struct ContentView: View {
var isAnimating = true
var body: some View {
ActivityIndicator(isAnimating: isAnimating)
}
}
UIViewController in SwiftUI
UIViewControllerRepresentable
- 要使 UIViewController 在 SwiftUI 中可用,需要用
UIViewControllerRepresentable对 UIViewController 进行包装。 UIViewControllerRepresentable中主要有 2 个方法需要实现。makeUIViewController():创建UIViewController。updateUIViewController():根据条件与业务逻辑设置UIViewController的状态。
案例
使用 UIKit 中的UINavigationController。
import SwiftUI
import UIKit
struct NavigationViewController: UIViewControllerRepresentable {
var vc: UIViewController
var title: String
func makeUIViewController(context: Context) -> UINavigationController {
let nvc = UINavigationController(rootViewController: vc)
return nvc
}
func updateUIViewController(_ navigationController: UINavigationController, context: Context) {
navigationController.viewControllers[0].title = title
}
}
struct ContentView: View {
var body: some View {
NavigationViewController(vc: UIViewController(), title: "UIViewControllerRepresentable")
}
}
SwiftUI in UIKit
UIKit 中使用 SwiftUI,需要通过UIHostingController包装 View,然后才能使用。
// 可以是复杂的ContentView
let vc = UIHostingController(rootView: ContentView())
// 也可以是简单的Text等其他View
let vc = UIHostingController(rootView: Text("Hello SwiftUI"))