以下代码取自 Compose demo 中的Imageviewer
struct ContentView: View {
var body: some View {
ZStack {
ComposeView()
.ignoresSafeArea(.all) // Compose has own keyboard handler
VStack {
gradient.ignoresSafeArea(edges: .top).frame(height: 0)
Spacer()
}
}.preferredColorScheme(.dark)
}
}
struct ComposeView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
let controller = Main_iosKt.MainViewController()
controller.overrideUserInterfaceStyle = .light
return controller
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
}
}
这里先介绍一下 UIViewControllerRepresentable
UIViewControllerRepresentable 是 SwiftUI 提供的一个协议,用于把 UIKit 的 UIViewController 控件包装成 SwiftUI 可以使用的视图。这样你就可以在 SwiftUI 界面中直接嵌入和复用原有的 UIKit 控件,比如图片选择器、地图、相机等。
使用方法是:
1. 创建一个结构体,遵循 UIViewControllerRepresentable 协议。
2. 实现两个必须的方法:
- makeUIViewController(context:) :创建并返回你的 UIKit 控件实例。
- updateUIViewController(_:context:) :当 SwiftUI 状态变化时,用于同步更新 UIKit 控件。
示例:
struct MyControllerWrapper: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> MyViewController {
MyViewController()
}
func updateUIViewController(_ uiViewController: MyViewController, context: Context) {
// 这里可以根据需要更新 UI
}
}
跟UIViewControllerRepresentable 类似的还有 UIViewRepresentable 用来处理UIView的
示例:
struct MyLabel: UIViewRepresentable {
func makeUIView(context: Context) -> UILabel {
let label = UILabel()
label.text = "Hello, UIKit!"
return label
}
func updateUIView(_ uiView: UILabel, context: Context) {
// 更新逻辑
}
}
所以ComposeView 就是使用 UIViewControllerRepresentable 把Compose视图包装到了 MainViewController(UIViewController)中 然后添加到SwiftUI中。
MainViewController 又是什么呢?
MainViewController 是在shared-iosMain下面的一个kotlin文件定义的一个方法,这个方法返回的就是UIViewController对应ios的UIViewController。
fun MainViewController(): UIViewController =
ComposeUIViewController {
ImageViewerIos()
}
ImageViewerIos() 就是我们自己写的Compose视图。