SwiftUI:SwiftUI与UIKit互相调用

在 SwiftUI 中调用 UIKit

在 SwiftUI 中使用 UIKit 需要用到UIViewRepresentableUIViewControllerRepresentable两个协议,分别对应在 SwiftUI 中使用UIViewUIViewController

在 SwiftUI 中使用 UIView

在 SwiftUI 中使用UIView需要实现UIViewRepresentable协议,如下代码实现了在 SwiftUI 的List控件中使用UITableViewCell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
struct TableViewCell: UIViewRepresentable {
@Binding var text: String
func makeUIView(context: UIViewRepresentableContext<TableViewCell>) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
cell.textLabel?.text = text
cell.selectionStyle = .gray
return cell
}

func updateUIView(_ uiView: UITableViewCell, context: Context) {
uiView.textLabel?.text = text
}
}

struct ContentView : View {
@State var text: String = "hello"
var body: some View {
List(0...5) { idx in
TableViewCell(text: self.$text)
}
}
}

#if DEBUG
struct ContentView_Previews : PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif

在 SwiftUI 中使用 UIViewController

在 SwiftUI 中使用UIViewController需要实现UIViewControllerRepresentable协议,如下示例展示了怎么从一个 SwiftUI 页面跳转到UIViewController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
struct MyViewController: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
let vc = UIViewController()
vc.view.backgroundColor = UIColor.white
return vc
}

func updateUIViewController(_ uiViewController: UIViewController, context: Context) {

}
}

struct ContentView : View {
@State var text: String = "hello"
var body: some View {
NavigationView {
NavigationLink(destination:
MyViewController()
.navigationBarTitle("My ViewController", displayMode: .inline)
) {
Text("Click to push")
}
}
}
}

在 UIKit 中调用 SwiftUI

在 UIKit 中使用 SwiftUI 要比在 SwiftUI 中使用 SwiftUI 简单很多,只需要使用UIHostingController对 SwiftUI 的控件进行一下包装就可以,代码如下:

1
let vc = UIHostingController(rootView: Text("Hello World"))

包装出来的结果是一个UIViewController,这样就可以在其他UIViewUIViewController中使用了。可以将这个UIViewController作为一个childViewController加到其他的UIViewUIViewController中去