LoginSignup
2
4

More than 1 year has passed since last update.

【SwiftUI】UIViewRepresentableについて

Posted at

はじめに

SwiftUIでUIKitを使う場合はUIViewRepresentableを使いますが、あらためて公式ドキュメントで使い方を確認してみました。

内容

Viewの作成と更新

func makeUIView(context: Self.Context) -> Self.UIViewType
  • 必須
  • Viewのオブジェクトを作成、初期状態を構成する
  • Viewを初めて作成するときに、このメソッドを1回だけ呼び出す
func updateUIView(_ uiView: Self.UIViewType, context: Self.Context)
  • 必須
  • Viewの状態をSwiftUIからの新しい情報で更新する
  • SwiftUIは、対応するUIKitのVIewに影響を与える変更に対してこのメ​​ソッドを呼び出す
  • パラメーターで提供される新しい状態情報に一致するようにビューの構成を更新する

サイズの指定

func sizeThatFits(_ proposal: ProposedViewSize, uiView: Self.UIViewType, context: Self.Context) -> CGSize?
  • iOS16から使える
  • 提案サイズからViewのサイズを指定する

Viewのクリーンアップ

static func dismantleUIView(_ uiView: Self.UIViewType, coordinator: Self.Coordinator)
  • Viewに関連する追加のクリーンアップ作業を実行する
  • たとえば、オブザーバーを削除するなど

Coordinatorの提供

func makeCoordinator() -> Self.Coordinator
  • Viewの変更がアプリの他の部分に影響を与える可能性がある場合は、このメソッドを実装する
  • UIKitのdelegateを使う場合などでも使う

実装例

AppleログインのボタンをUIViewRepresentableを使って実装した場合のイメージ👇

import SwiftUI
import AuthenticationServices

struct CustomButton: UIViewRepresentable {
    @ObservedObject var viewModel: SampleViewModel

    func makeUIView(context: Context) -> UIButton {
        var configuration = UIButton.Configuration.plain()
        var container = AttributeContainer()
        container.font = UIFont.boldSystemFont(ofSize: 16.0)
        configuration.attributedTitle = AttributedString("Apple Login", attributes: container)
        configuration.baseBackgroundColor = .white
        configuration.background.strokeWidth = 1.0

        let button = UIButton(configuration: configuration)
        button.addTarget(context.coordinator,
                         action: #selector(Coordinator.didTapButton),
                         for: .touchUpInside)
        return button
    }

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

    func makeCoordinator() -> Coordinator {
        Coordinator(customButton: self)
    }

    class Coordinator: NSObject, ASAuthorizationControllerDelegate {
        var customButton: CustomButton

        init(customButton: CustomButton) {
            self.customButton = customButton
        }

        @objc func didTapButton() {
            let provider = ASAuthorizationAppleIDProvider()
            let request = provider.createRequest()
            request.requestedScopes = [.fullName, .email]
            let controller = ASAuthorizationController(authorizationRequests: [request])
            controller.delegate = self
            controller.performRequests()
        }

        func authorizationController(controller: ASAuthorizationController,
                                     didCompleteWithAuthorization authorization: ASAuthorization) {
            // ViewModelで処理するなど   customButton.viewModel.loginWithApple()
        }

        func authorizationController(controller _: ASAuthorizationController, didCompleteWithError error: Error) {
            // ViewModelで処理するなど   customButton.viewModel.showError()
        }
    }
}

おわりに

とくに整理する程の内容量ではないですが、iOS16から使えるsizeThatFitsは少し実装で使って試していきたいと思いました。

参考

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4