😺

[UIView/UIViewController]Representableをマルチプラットフォームに対応させる[SwiftUI]

2022/08/04に公開

UIView/NSView

  • UIView/ UIViewController(iOS, iPadOS, tvOS, watchOS)
  • NSView/ NSViewController(macOS)

上の4つはUIKitで使われている基本要素です。

Representable

UIKitをそのままSwiftUIで使えるようにするのがRepresentableです。

  • UIViewRepresentable, UIViewControllerRepresentable
  • NSViewRepresentable, NSViewControllerRepresentable

マルチプラットフォーム

iOSとMacで1つのコードで同じViewを使用方法を紹介します。
Appleのサンプルコードでも同じように実装されていました。

基本はtypealiasを使ってOS分岐をしていきます。

https://github.com/apple/sample-food-truck/blob/main/App/City/DetailedMapView.swift

コード

Live Photoを表示するPHLivePhotoをSwiftUIでも使えるようにしてきます。

import SwiftUI
import PhotosUI

#if os(macOS)
typealias ViewRepresentable = NSViewRepresentable
#else
typealias ViewRepresentable = UIViewRepresentable
#endif

struct LivePhotoView: ViewRepresentable {
  let livePhoto: PHLivePhoto

  #if os(macOS)
  func makeNSView(context: Context) -> some NSView {
    let livePhotoView = PHLivePhotoView(frame: .zero)
    livePhotoView.livePhoto = livePhoto
    return livePhotoView
  }

  func updateNSView(_ nsView: NSViewType, context: Context) { }

  #else
  func makeUIView(context: Context) -> PHLivePhotoView {
    let livePhotoView = PHLivePhotoView()
    livePhotoView.livePhoto = livePhoto
    return livePhotoView
  }

  func updateUIView(_ livePhotoView: PHLivePhotoView, context: Context) {}
  #endif
}

Discussion