[SwiftUI][macOS] Table の使い方

SwiftUI2021

macOS12 から使用可能になっている Table の使い方を説明します。

環境&対象

以下の環境で動作確認を行なっています。

  • macOS Monterey 12.1 Beta
  • Xcode 13.1
  • iOS 15

Table ビュー

macOS12 以前は、表形式のビューは、リストだけでした。

テーブル的な見た目を再現するために、各セルの横幅の調整に苦労することが多くありました。

macOS12 の SwiftUI で導入されたのが、Table ビューです。

Apple のドキュメントは、こちら

MEMO
AppKit であれば、NSTableView が初期から用意されていました。この NSTableView 相当を SwiftUI で再現することに苦労していました。

細かい挙動については、Table を用いても、まだ苦労します・・・

カラムの位置合わせだけでなく、以下のような 1行おきの色も再現可能です。

Table

一番やさしい Table ビューの使い方

一番シンプルな使い方を見てみます。

データに対して、各行に表示するデータを KeyPath で指定します。

注意
KeyPath で取得できるデータは、String であることが必要です。
Table


//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2021/06/10
//  © 2021  SmallDeskSoftware
//

import SwiftUI

struct Person: Identifiable {
    public let id = UUID()
    public var givenName: String
    public var familyName: String
}

private var personList = [
    Person(givenName: "Juan", familyName: "Chavez"),
    Person(givenName: "Mei", familyName: "Chen"),
    Person(givenName: "Tom", familyName: "Clark"),
    Person(givenName: "Gita", familyName: "Kumar"),
]
struct ContentView: View {
    @State private var persons = personList

    var body: some View {
        VStack {
            // (1)
            Table(persons) {
                // (2)
                TableColumn("Given Name", value:\.givenName)
                // (2)
                TableColumn("Family Name", value:\.familyName)
            }
        }
    }
}
コード解説
  1. persons というデータにたいして、テーブルを表示します
  2. 1つめの行は、"Given Name" というタイトルで、.givenName という KeyPath で取得できるデータを表示します
  3. 2つめの行は、"Family Name" というタイトルで、.familyName という KeyPath で取得できるデータを表示します

セルの表示を少し凝った Table ビュー

String 型のデータを表示するテーブルをすこし凝った表示にします。

凝った表示の例として、表示書体を Bold にし、”〜家”のような -family を付与する表示にしています。

TableRev2

//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2021/06/10
//  © 2021  SmallDeskSoftware
//

import SwiftUI

struct Person: Identifiable {
    public let id = UUID()
    public var givenName: String
    public var familyName: String
}

private var personList = [
    Person(givenName: "Juan", familyName: "Chavez"),
    Person(givenName: "Mei", familyName: "Chen"),
    Person(givenName: "Tom", familyName: "Clark"),
    Person(givenName: "Gita", familyName: "Kumar"),
]
struct ContentView: View {
    @State private var persons = personList

    var body: some View {
        VStack {
            // (1)
            Table(persons) {
                // (2)
                TableColumn("Given Name", value:\.givenName)
                // (3)
                TableColumn("Family Name") { person in
                    // (4)
                    Text("\(person.familyName)-family").bold()
                }
            }
        }
    }
}
コード解説
  1. 最初の例と同じで、persons というデータを Table 表示します
  2. 最初の例と同じで、1つめの列は "Given Name" というタイトルで、.givenName という KeyPath で取得できる値を表示します
  3. 2つめの列は、person.familyName で取得できる値に "-family" という文字列を追加し、bold フォントで表示します

このように、TableColumn には、要素が与えられる closure でその列のセルを作成することもできるようになっています。

選択できる Table ビュー

SwiftUI の List と同様に、選択できるような Table を表示することも可能です。

1つだけ選択できる Table ビュー

1つの行を選択できる Table ビューです。

おおよそ SwiftUI の List での選択と同様に使用できます。


//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2021/06/10
//  © 2021  SmallDeskSoftware
//

import SwiftUI

struct Person: Identifiable {
    public let id = UUID()
    public var givenName: String
    public var familyName: String
}

private var personList = [
    Person(givenName: "Juan", familyName: "Chavez"),
    Person(givenName: "Mei", familyName: "Chen"),
    Person(givenName: "Tom", familyName: "Clark"),
    Person(givenName: "Gita", familyName: "Kumar"),
]
struct ContentView: View {
    @State private var persons = personList
    // (1)
    @State private var selection:Person.ID? = nil

    var body: some View {
        VStack {
            // (2)
            Table(persons, selection: $selection) {
                TableColumn("Given Name", value:\.givenName)
                TableColumn("Family Name") { person in
                    Text("\(person.familyName)-family").bold()
                }
            }
        }
    }
}
コード解説
  1. 選択された要素を保持する変数を用意します (optional が必要であることも、List と同じです)
  2. 選択された要素を保持する変数を引数として、Table を宣言します

複数選択できる Table ビュー

複数選択できる Table ビューも簡単です。

こちらも、SwiftUI での List での複数選択と同じ要領です。

# macOS では、複数選択は、⌘+左クリックで行います。


//
//  ContentView.swift
//
//  Created by : Tomoaki Yagishita on 2021/06/10
//  © 2021  SmallDeskSoftware
//

import SwiftUI

struct Person: Identifiable {
    public let id = UUID()
    public var givenName: String
    public var familyName: String
}

private var personList = [
    Person(givenName: "Juan", familyName: "Chavez"),
    Person(givenName: "Mei", familyName: "Chen"),
    Person(givenName: "Tom", familyName: "Clark"),
    Person(givenName: "Gita", familyName: "Kumar"),
]
struct ContentView: View {
    @State private var persons = personList
    // (1)
    @State private var selections:Set = Set()

    var body: some View {
        VStack {
            // (2)
            Table(persons, selection: $selections) {
                TableColumn("Given Name", value:\.givenName)
                TableColumn("Family Name") { person in
                    Text("\(person.familyName)-family").bold()
                }
            }
        }
    }
コード解説
  1. 選択要素を複数保持するために、Set 型の変数を用意します
  2. 選択された要素を保持する変数を引数として、Table を宣言します

まとめ:SwiftUI Table の使い方

SwiftUI Table の使い方
  • Table 定義時に、表示対象データを指定する
  • TableColumn 定義時に表示するデータの KeyPath を指定する
  • TableColumn 定義時に元データから表示データを生成することも可能
  • 選択可能にするには、オプショナル変数を Table 定義時に渡す

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です