SwiftUIにUIKitのViewを組み込む
struct UILabelRepresentable: UIViewRepresentable {
var count: Int
// UIKitのViewの生成、初期設定を行う
func makeUIView(context: Context) -> UILabel {
let label = UILabel()
label.textAlignment = .center
return label
}
// SwiftUIのViewの状態が更新された時の処理を書く
func updateUIView(_ uiView: UILabel, context: Context) {
uiView.text = "Count: \(count)"
}
}
struct ContentView: View {
@State private var count = 0
var body: some View {
VStack {
UILabelRepresentable(count: count)
Button("Increment") {
count += 1
}
}
}
}
UIViewRepresentable
SwiftUIのViewの中でUIKitのViewを使用するためのプロトコル。このプロトコルに準拠したstructを使い、必須メソッドを含む要件を実装したViewを作成する。
必須メソッド
-
makeUIView(context:)
UIKitのViewの生成、初期設定を実装する。UIKitのViewを初めて作成するときに、このメソッドを1回だけ呼び出す。2回目以降は下記のupdateUIView(_:context:)が呼ばれる。 -
updateUIView(_:context:)
組み込み元のSwiftUIのViewの状態が更新された時の処理を実装する。
SwiftUIにUIKitのViewControllerを組み込む
class CounterViewController: UIViewController {
private let label = UILabel()
var count: Int = 0 {
didSet {
label.text = "Count: \(count)"
}
}
override func viewDidLoad() {
super.viewDidLoad()
label.frame = view.bounds
label.textAlignment = .center
view.addSubview(label)
label.text = "Count: \(count)"
}
}
struct CounterViewControllerRepresentable: UIViewControllerRepresentable {
// 使用するUIViewControllerを指定
typealias UIViewControllerType = CounterViewController
var count: Int
// 指定したUIViewControllerを生成、初期設定を行う
func makeUIViewController(context: Context) -> CounterViewController {
let vc = CounterViewController()
return vc
}
// SwiftUIのViewの状態が更新された時の処理を書く
func updateUIViewController(_ uiViewController: CounterViewController, context: Context) {
uiViewController.count = count
}
}
struct ContentView_WithVC: View {
@State private var count = 0
var body: some View {
VStack {
CounterViewControllerRepresentable(count: count)
Button("Increment") {
count += 1
}
}
}
}
UIViewControllerRepresentable
SwiftUIのViewの中でUIKitのViewControllerを使用するためのプロトコル。このプロトコルに準拠したstructを使い、必須メソッドを含む要件を実装したViewを作成する。
必須メソッド
-
makeUIViewController(context:)
UIKitのViewControllerの生成、初期設定を実装する。UIKitのViewControllerを初めて作成するときに、このメソッドを1回だけ呼び出す。2回目以降は下記のupdateUIViewController(_:context:)が呼ばれる。 -
updateUIViewController(_:context:)
組み込み元のSwiftUIのViewの状態が更新された時の処理を実装する。
UIKitにSwiftUIのViewを組み込む
struct CounterView: View {
@State private var count = 0
var body: some View {
VStack {
Text("Count: \(count)")
Button("Increment") {
count += 1
}
}
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let swiftUIView = CounterView()
// UIViewControllerとして表現できるように変換する。
let hostingController = UIHostingController(rootView: swiftUIView)
// 以降UIViewControllerとして操作可能
addChild(hostingController)
hostingController.view.frame = view.bounds
view.addSubview(hostingController.view)
hostingController.didMove(toParent: self)
}
}
UIHostingController
SwiftUIのViewをUIKitの画面構成に組み込むために使用する。UIViewControllerのサブクラスであり、SwiftUIのViewをUIKitのUIViewControllerとして扱えるようにする役割を持つ。これによりUIKitのライフサイクルを利用したり、コンテナクラス(UINavigationControllerなど)への統合などが可能になる。
参考文献
【SwiftUI】UIViewRepresentableについて
UIKitのUIViewController/UIViewをSwiftUIで利用する場合の利用方法とその詳細
UIKitからSwiftUI移行期に使うUIHostingControllerって何してるのか?
UIViewRepresentable
UIViewControllerRepresentable
UIHostingController