SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

iOS16の新機能に触れてみよう

iOS16/SwiftUI4の新しいデータ共有とUIの表示形式をサンプルと共に学ぶ

iOS16の新機能に触れてみよう 第2回

  • X ポスト
  • このエントリーをはてなブックマークに追加

情報共有をより手軽に──Sharing

 スマートフォンやSNSアプリの普及とともに、もはや当たり前となった情報やデータの共有がより簡単に利用できるようになりました。主要な変更点について、Photos/Splits Sharing/Transferableの3つでまとめられています。

SwiftUI 4での主要な変更点
ジャンル 概要
Photos 画像/動画ファイルのピッカー
Sharing 情報の共有
Transferable データの共有

 それぞれの項目について簡単なサンプルコードとともに紹介します。

Photos

 端末の写真ライブラリから画像ファイルや動画ファイルを選択するPhotosPicker構造体が新しく定義されました。PhotosPickerでは、画像や象画をスクリーンショットやライブ写真など種類を指定して複数選択することができます。PhotosPickerを利用して複数の画像を選択して画面に表示するサンプルは次のようになります。

[リスト1]PhotosSample/ContentView.swift抜粋
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)
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
Photosの例
Photosの例

 PhotosPickerを利用する前に、PhotosUIフレームワークをインポートします。(①)。ツールバーの右側のボタンでPhotosPickerを起動します(②)。起動時には、選択した画像/動画を格納する変数、選択できるファイル数の上限、選択するファイルの種類を指定できます。選択できるファイルの種類はAppleのドキュメントで確認できます。

 PhotosPickerで画像を選択した後の処理は、onChangeメソッドで行います(③)。選択した画像は、PhotosPickerItemオブジェクトとして得られます。サンプルでは、選択した画像をスクロールビュー上に画面サイズに合わせて表示しますので、いったんPhotosPickerItemオブジェクトをDataオブジェクトに変換してバインディング変数に格納しています。最後にバインディング変数内のDataオブジェクトをImageオブジェクトに変換してスクロールビューの幅に合わせてサイズ変換後、表示します(④)。

Sharing

 一般的に使われる「シェアする」に該当する機能です。新しく追加されたShareLink構造体を配置することで、シェアする機能を実装できます。

[リスト2]ShareLinkSample/ContentView.swift抜粋
struct ContentView: View {
    let url = URL(string: "https://www.apple.com")!
    
    var body: some View {
        VStack {
            ShareLink(item: url)    // -------- ①
        }
    }
}
Sharingの例
Sharingの例

 ShareLinkをシェアしたいURLで初期化して設置します(①)。これだけで、アイコンの設置とクリックした後のシェアするメニュー画面を表示できます。シェアのために特別な処理を行う必要がなくなりました。

Transferable

 Transferableは、ドラッグ/ドロップ/コピー/ペーストなどの機能を実装するために追加された新しいプロトコルです。連載第1回の「チャートの生成が容易に──Swift Chartsフレームワーク」で作成した月当たりの売り上げデータのサンプルを使ってドラッグ&ドロップのサンプルを作成してみます。手順は次のとおりです。

  1. ドラッグ&ドロップを行う構造体を用意
  2. データを送受信する型を定義
  3. 1と2を紐づけてTransferableプロトコルを実装
  4. ドラッグ&ドロップの動作をUIに実装
[リスト3]TransferableSample/ContentView.swift抜粋
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で項目を追加します。

Info項目追加
Info項目追加

 サンプルでは、ドラッグ&ドロップの動きが確認できれば十分なので、Identifierの項目のみを設定しています。他の項目についてはAppleのドキュメントで確認してください。

 最後に、ドラッグ&ドロップを行う構造体でTransferableプロトコルを実装します。転送を可能とするCodableRepresentation構造体で(1)と(2)を紐づけます。

 ドラッグ&ドロップを実際に行う部分のコードは次のようになります。

[リスト4]TransferableSample/ContentView.swift抜粋
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)。

Transferableの例
Transferableの例

 ドラッグ&ドロップする対象を長押しすることで、ドラッグ可能となります。ドロップする領域まで移動すると、右上に「+」マークが表示されてドロップ可能であることが分かります。

次のページ
より高度な表現が可能となった──Graphics and Layout

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
iOS16の新機能に触れてみよう連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 片渕 彼富(カタフチ カノトミ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/16719 2022/11/21 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング