SwiftUIからUIKitの部品を使う
概要
SwiftUIからUIKitの部品を使うときの方法を紹介します。
サンプル用にシンプルな動作を考えました。
ボタンタップ時にラベルの文字列を変えるだけです。
動画にすると下のような感じです。
環境
Xcode 13.1
macOS Big Sur 11.6
手順
-
UIViewRepresentable
に準拠した構造体を作る -
UIKit
から画面を作成するためにmakeUIView
を実装する - 作成した画面が更新できるように
updateUIView
を実装する -
UIKit
からSwiftUI
が保持している値を変更できるようにする
キーワードの解説
SwiftUIからUIKitを扱うにあたりキーワードがいくつかあります。
代表的なのはmakeUIView(context:)
, updateUIView(_:context:)
, Coordinator
です。
公式の説明を下に載せます。
makeUIView(context:)
ビューオブジェクトを作成し、その初期状態を構成します。
updateUIView(_:context:)
SwiftUIからの新しい情報で、指定されたビューの状態を更新します。
Coordinator
- システムは、ビュー内で発生した変更をSwiftUIインターフェースの他の部分に自動的に伝達しません。
- ビューを他のSwiftUIビューと調整する場合は、それらの相互作用を容易にするためにCoordinatorインスタンスを提供する必要があります。
- たとえば、コーディネーターを使用して、ターゲットアクションを転送し、ビューから任意のSwiftUIビューにメッセージを委任します。
実装
以下実装を進めます。
ボタンの初期状態を実装する
makeUIView(context:)
でUIButton
を返してあげます。
struct CustomButton: UIViewRepresentable {
func makeUIView(context: Context) -> UIButton {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 160, height: 44))
button.setTitle("Custom Button", for: .normal)
button.setTitleColor(.black, for: .normal)
button.addTarget(context.coordinator, action: #selector(Coordinator.didTapCustomButton(sender:)), for: .touchUpInside)
return button
}
}
ボタンのスタイルを更新するためのメソッドを追加する
中身は空ですがUIViewRepresentable
プロトコルに準拠するために必須のメソッドです。
struct CustomButton: UIViewRepresentable {
...
func updateUIView(_ uiView: UIButton, context: Context) {
}
...
}
ボタンタップ時にラベルの文字列を変更できるようにCoordinator
クラスを実装する
名前解決にもつながるため、CustomButton
クラスの中でCoordinator
を宣言します。
struct CustomButton: UIViewRepresentable {
...
func makeCoordinator() -> Coordinator {
return Coordinator(button: self)
}
class Coordinator {
var button: CustomButton
init(button: CustomButton) {
self.button = button
}
@objc func didTapCustomButton(sender: UIButton) {
if button.text == "Default" {
button.text = "Change"
return
}
button.text = "Default"
}
}
...
}
最終的なコードは以下です。
import SwiftUI
struct CustomButton: UIViewRepresentable {
@Binding var text: String
func makeUIView(context: Context) -> UIButton {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 160, height: 44))
button.setTitle("Custom Button", for: .normal)
button.setTitleColor(.black, for: .normal)
button.addTarget(context.coordinator, action: #selector(Coordinator.didTapCustomButton(sender:)), for: .touchUpInside)
return button
}
func updateUIView(_ uiView: UIButton, context: Context) {
}
func makeCoordinator() -> Coordinator {
return Coordinator(button: self)
}
class Coordinator {
var button: CustomButton
init(button: CustomButton) {
self.button = button
}
@objc func didTapCustomButton(sender: UIButton) {
if button.text == "Default" {
button.text = "Change"
return
}
button.text = "Default"
}
}
}
SwiftUIから呼び出す
UIKitの部品をSwiftUIから呼び出します。
記事では以下のようにしました。
import SwiftUI
struct Home: View {
@State var text: String = "Default"
var body: some View {
VStack {
Text(text)
CustomButton(text: $text)
}
}
}
struct Home_Previews: PreviewProvider {
static var previews: some View {
Home()
}
}
以上のコードで動画のような動作になると思います。
Author And Source
この問題について(SwiftUIからUIKitの部品を使う), 我々は、より多くの情報をここで見つけました https://qiita.com/h-taro/items/4bce23668c29e9c11b97著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .