UIViewRepresentableプロトコルとは?
UIKitのViewや機能をSwiftUIでも使えるようにするラッパー的役割
を持つ。
ちなみに、ラップして違うフレームワークを使用可能にする組み合わせは下記である。
- UIKitをSwiftUIで使用 → UIViewRepresentableプロトコル
- SwiftUIをUIKitで使用 → UIHostingControllerクラス
主なメソッド
-
makeUIViewメソッド
- 表示するViewの初期状態のインスタンスを作るメソッド。SwiftUIの中で使用したいUIKitのViewを戻り値として返す。
- 最初の一回しか呼び出されない。そのため、Viewを更新する場合はupdateUIViewメソッドに処理を定義する。
-
updateUIViewメソッド
- 表示するViewの状態が更新されるたびに呼び出され、更新を反映させる。
- 例えば、UIViewRepresentableプロトコルに準拠させた構造体のプロパティなどが変更されたときに呼び出される。
ソースコード
- SwiftUIの変更を(SwiftUIで使えるようにラップした)UIKitに伝える
Swift
// UILabel(UIKit)をSwiftUIで表示させ、SwiftUI内でボタンを作成し、そのボタンをクリックしたときにラベルのテキストを変更させる
// UIKitをSwiftUIで使う(View構造体として扱う)
struct LabelView: UIViewRepresentable {
@Binding var isClick: Bool
// 初期状態のインスタンスを生成
func makeUIView(context: Context) -> UILabel {
let labelView = UILabel()
labelView.text = "UIKitで作成したView"
labelView.textAlignment = NSTextAlignment.center
return labelView
}
// インスタンスの更新など
func updateUIView(_ uiView: UIViewType, context: Context) {
if isClick {
// UILabel
uiView.text = "ボタンが押されました"
} else {
uiView.text = "UIKitで作成したView"
}
}
}
// SwiftUIの変更を(SwiftUIで使えるようにラップした)UIKitに伝える
struct ContentView: View {
@State var isClick: Bool = false
var body: some View {
VStack {
// ラップしたLabelViewを使用する
LabelView(isClick: $isClick)
Button("ボタン") {
isClick.toggle()
}
}
}
}
おわりに
間違い等ありましたらコメント欄にてご指摘ください!
参考記事
開発環境
- Xcode-14.3
- Swift version 5.8