情報共有をより手軽に──Sharing
スマートフォンやSNSアプリの普及とともに、もはや当たり前となった情報やデータの共有がより簡単に利用できるようになりました。主要な変更点について、Photos/Splits Sharing/Transferableの3つでまとめられています。
ジャンル | 概要 |
---|---|
Photos | 画像/動画ファイルのピッカー |
Sharing | 情報の共有 |
Transferable | データの共有 |
それぞれの項目について簡単なサンプルコードとともに紹介します。
Photos
端末の写真ライブラリから画像ファイルや動画ファイルを選択するPhotosPicker構造体が新しく定義されました。PhotosPickerでは、画像や象画をスクリーンショットやライブ写真など種類を指定して複数選択することができます。PhotosPickerを利用して複数の画像を選択して画面に表示するサンプルは次のようになります。
import SwiftUI import PhotosUI // -------- ① struct ContentView: View { @State private var selectedItems: [PhotosPickerItem] = [] @State private var selectedPhotosData: [Data] = [] var body: some View { NavigationStack { ScrollView { VStack { // 選択した画像を並べて表示 ForEach(selectedPhotosData, id: \.self) { photoData in // -------- ④ if let image = UIImage(data: photoData) { Image(uiImage: image) .resizable().scaledToFit().padding(.horizontal) } } } }.toolbar { ToolbarItem(placement: .navigationBarTrailing) { // 画像ピッカーを表示 PhotosPicker(selection: $selectedItems, maxSelectionCount: 5, matching: .images) { // -------- ② Image(systemName: "photo.on.rectangle.angled") } // 画像選択後の処理 .onChange(of: selectedItems) { items in // -------- ③ for item in items { Task { if let data = try? await item.loadTransferable(type: Data.self) { selectedPhotosData.append(data) } } } } } } } } }
PhotosPickerを利用する前に、PhotosUIフレームワークをインポートします。(①)。ツールバーの右側のボタンでPhotosPickerを起動します(②)。起動時には、選択した画像/動画を格納する変数、選択できるファイル数の上限、選択するファイルの種類を指定できます。選択できるファイルの種類はAppleのドキュメントで確認できます。
PhotosPickerで画像を選択した後の処理は、onChangeメソッドで行います(③)。選択した画像は、PhotosPickerItemオブジェクトとして得られます。サンプルでは、選択した画像をスクロールビュー上に画面サイズに合わせて表示しますので、いったんPhotosPickerItemオブジェクトをDataオブジェクトに変換してバインディング変数に格納しています。最後にバインディング変数内のDataオブジェクトをImageオブジェクトに変換してスクロールビューの幅に合わせてサイズ変換後、表示します(④)。
Sharing
一般的に使われる「シェアする」に該当する機能です。新しく追加されたShareLink構造体を配置することで、シェアする機能を実装できます。
struct ContentView: View { let url = URL(string: "https://www.apple.com")! var body: some View { VStack { ShareLink(item: url) // -------- ① } } }
ShareLinkをシェアしたいURLで初期化して設置します(①)。これだけで、アイコンの設置とクリックした後のシェアするメニュー画面を表示できます。シェアのために特別な処理を行う必要がなくなりました。
Transferable
Transferableは、ドラッグ/ドロップ/コピー/ペーストなどの機能を実装するために追加された新しいプロトコルです。連載第1回の「チャートの生成が容易に──Swift Chartsフレームワーク」で作成した月当たりの売り上げデータのサンプルを使ってドラッグ&ドロップのサンプルを作成してみます。手順は次のとおりです。
- ドラッグ&ドロップを行う構造体を用意
- データを送受信する型を定義
- 1と2を紐づけてTransferableプロトコルを実装
- ドラッグ&ドロップの動作をUIに実装
import SwiftUI import UniformTypeIdentifiers struct MonthAmount: Identifiable, Codable { // (1) var id = UUID() var month: String var amount: Double } extension UTType { // (2) static var monthAmount: UTType { UTType(exportedAs: "com.yourcompany.TransferableSample") } } extension MonthAmount: Transferable { // (3) static var transferRepresentation: some TransferRepresentation { CodableRepresentation(for: MonthAmount.self, contentType: UTType.monthAmount) } }
ドラッグ&ドロップを行う構造体にTransferableプロトコルを実装するために、Codableプロトコルを実装します(1)。Codableプロトコルに関しては、「Swift 4で最初に知っておきたい3つのポイント」連載の第2回で確認できます。データを送受信する構造体UTTypeを用いて、アプリが所有する型を定義します。このときに識別子が必要なので、サンプルのBundle Identifierを用いています(2)。
(2)と同時にXcodeの「TARGETS」ー「TransferableSample」ー「Info」ー「Expoted Type Identifiers」内に(2)と同じIdentifierで項目を追加します。
サンプルでは、ドラッグ&ドロップの動きが確認できれば十分なので、Identifierの項目のみを設定しています。他の項目についてはAppleのドキュメントで確認してください。
最後に、ドラッグ&ドロップを行う構造体でTransferableプロトコルを実装します。転送を可能とするCodableRepresentation構造体で(1)と(2)を紐づけます。
ドラッグ&ドロップを実際に行う部分のコードは次のようになります。
struct ContentView: View { @State var selectedMonthAmount: MonthAmount? var body: some View { VStack { ForEach(MonthAmount.examples) { item in // 月当たりの売り上げデータをリストで表示 Text("\(item.month) \(item.amount)") .padding(4) .draggable(item) { // (4-1) Text("\(item.month) ドラッグ中") .bold().padding() .foregroundColor(.white) .background(Color.blue) } } Rectangle() // ドロップ先の矩形 .foregroundColor(.gray) .frame(width: 200, height: 200) .overlay { // (4-3) if let selectedMonthAmount { Text("\(selectedMonthAmount.month) \(selectedMonthAmount.amount)" ) } else { Text("ドラッグ & ドロップ") } } .dropDestination(for: MonthAmount.self) { data, location in // (4-2) selectedMonthAmount = data.first! return true } } } }
ドラッグ&ドロップを行う構造体に対して、draggableメソッドでドラッグ時の処理を定義します。サンプルではドラッグ中には青い背景に白い太字で選択した月名を表示するようにしています(4-1)。ドロップ先には矩形のViewを設け、dropDestinationメソッドでドロップ時の処理を定義します(4-2)。ドロップ時には、ドロップしたオブジェクトと位置情報が渡されますので、ドロップしたオブジェクトをバインディング変数に格納しています。バインディング変数の値が変わったときに、月名と売り上げを矩形上にテキストで表示します(4-3)。
ドラッグ&ドロップする対象を長押しすることで、ドラッグ可能となります。ドロップする領域まで移動すると、右上に「+」マークが表示されてドロップ可能であることが分かります。