💜

SwiftUIからUIKitのコードを呼ぶ

2024/01/05に公開

対象者

  • SwiftUIとUIKitを使ったことある人
  • ブリッジなるものをやってみたい

やること/やらないこと

やること:

  • SwiftUIからUIkitのコードを呼ぶ
  • ボタンを押すとダイアログを表示する

やらないこと:

  • UIkitについては詳しくは解説しません

プロジェクトの説明

SwiftUIからUIKitのボタンを使用するには、UIViewRepresentableプロトコルを実装する必要があります。以下にその例を示します。

まず、UIKitのボタンをラップするSwiftUIビューを作成します。これがブリッジってやつかな。

import SwiftUI
import UIKit

struct UIKitButton: UIViewRepresentable {
    func makeUIView(context: Context) -> UIButton {
        let button = UIButton(type: .system)
        button.setTitle("Press me", for: .normal)
        button.addTarget(context.coordinator, action: #selector(Coordinator.buttonTapped), for: .touchUpInside)
        return button
    }

    func updateUIView(_ uiView: UIButton, context: Context) {}

    func makeCoordinator() -> Coordinator {
        Coordinator()
    }

    class Coordinator {
        @objc func buttonTapped() {
            let alert = UIAlertController(title: "Hello", message: "Hello UIKit", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default))
            UIApplication.shared.windows.first?.rootViewController?.present(alert, animated: true)
        }
    }
}

SwiftUIからUIKitのコードを読んでみた。ボタンを押すとダイアログが出ます。こちらはUIKitのボタンは、先ほどコンポーネントで作ってます。

//
//  ContentView.swift
//  UIExample
//
//  Created by 橋本純一 on 2024/01/04.
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            UIKitButton()
        }
        .padding()
    }
}




struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


感想

今回は、簡単にと言いたいいが難しかったUIKitで書いたコードをSwiftUIで呼ぶのをやってみました。UIを作るときに、SwiftUIでは表現できないものもあるらしく、UIKitをブリッジして使うのをやってみました。

私、UIKit好きではないのですが、必要な場面もあるので学んでみょうかなと思いましたね。以前は、ボタンをドラッグ&ドロップして呼ぶのをやってましたけど💦

ブリッジとは?

SwiftUIとUIKitの間のブリッジは、SwiftUIとUIKitの間でコンポーネントを共有するための方法です。これにより、既存のUIKitコードを再利用したり、UIKitが提供する一部の高度な機能をSwiftUIで利用したりすることができます。

SwiftUIからUIKitへのブリッジングは主に2つのプロトコル、UIViewRepresentableとUIViewControllerRepresentableを使用します。

UIViewRepresentable: このプロトコルを使用すると、SwiftUIビュー内でUIKitビューを使用できます。このプロトコルを実装するには、makeUIView(context:)とupdateUIView(:context:)の2つのメソッドを提供する必要があります。makeUIView(context:)メソッドは新しいUIKitビューを作成し、updateUIView(:context:)メソッドは既存のビューを更新します。

UIViewControllerRepresentable: このプロトコルを使用すると、SwiftUIビュー内でUIKitのビューコントローラを使用できます。これもUIViewRepresentableと同様に、makeUIViewController(context:)とupdateUIViewController(_:context:)の2つのメソッドを提供する必要があります。

これらのプロトコルを使用することで、SwiftUIとUIKitの間でシームレスにコンポーネントを共有することができます。ただし、可能な限りSwiftUIのコンポーネントを使用し、必要な場合にのみUIKitのコンポーネントを使用することが推奨されます。

https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundledocumenttypes

https://www.hackingwithswift.com/

Discussion