Appleは、Swiftの宣言型UIフレームワークであるSwiftUIをUIKitやAppKitと同レベルにするための取り組みを続けている。WWDC 2021で、SwiftUIは、拡張リストビュー、Pull-to-Refreshのサポート、非同期イメージなど、多くの新機能が追加された。
リストはiOSアプリ設計の基礎である。それでも、Appleが、最も一般的なインタラクションパラダイムの2つであるカスタムスワイプアクションのサポートとPull-to-RefreshをSwiftUI List
に追加するのに2年かかった。
SwiftUI 3を使うと、カスタムスワイプアクションをリストアイテムに追加できる。複数のボタンを追加してさまざまなアクションをサポートしたり、それらのアクションの1つをフルスワイプで実行されるデフォルトのアクションとして指定したりできる。これは、ディスプレイの両端からスワイプアクションを追加する方法である。
List {
ForEach(labels) { label in
Text(label)
.swipeActions(edge: .leading) {
Button { doAction(message) } { buttonImage }
}
.swipeActions(edge: .trailing) {
Button { doAnotherAction(message) } { anotherButtonImage }
}
}
}
同様に、[refreshable()
修飾子](https://developer.apple.com/documentation/swiftui/texteditor/refreshable(action:))を使って、ユーザが標準のジェスチャを行ったときに非同期操作をトリガーできるようになった。
List(mailbox.conversations) {
ConversationCell($0)
}
.refreshable {
await mailbox.fetch()
}
リストに関連するもう1つの重要な新機能は、[searchable
](https://developer.apple.com/documentation/swiftui/list/searchable(_:text:placement:suggestions:))修飾子を使った検索のサポートである。これをNavigationView
あるいはList
に添付して、ラベル、配置ヒント、オートコンプリートの提案を指定できる。
List {...}.searchable("Search", text: $value, placement: .automatic) {
Text("moniker1").searchCompletion("fullValue1")
Text("moniker2").searchCompletion("fullValue2")
...
}
他に、SwiftUIリストへ追加された便利なものとして、[listRowSeparatorTint
](https://developer.apple.com/documentation/SwiftUI/View/listRowSeparatorTint(_:edges:))、[listRowSeparator
](https://developer.apple.com/documentation/swiftui/view/listrowseparator(_:edges:))、[listSectionSeparatorTint
](https://developer.apple.com/documentation/swiftui/view/listsectionseparatortint(_:edges:))など、セクションとセルの区切り文字と色合いをスタイル設定するためのいくつかの修飾子がある。
SwiftUI 3は、ビュー内の非同期操作の先行サポートも提供する。特に、新しい[task
](https://developer.apple.com/documentation/swiftui/tabview/task(_:))修飾子を使うと、ビューが最初に表示されたときに非同期操作を開始できる。
Text(value).task { value = await asyncOp() }
task
はonAppear
に似ているが、特に非同期操作を対象としている。たとえば、ビューが消えると、非同期タスクは自動的にキャンセルされる。
さらに、AsyncImage
を使うと、リモートからダウンロードした画像を簡単に表示できる。リモート画像のダウンロード中に表示するプレースホルダー画像を指定し、クロージャーでリモート画像を操作できる。例えば、次のようにして、サイズ変更可能にできる。
AsyncImage(url: URL(string: "https://example.com/icon.png")) { image in
image.resizable()
} placeholder: {
ProgressView()
}
.frame(width: 50, height: 50)
SwiftUI3の機能で、ユーザが体感するものではないが、開発者の生活をはるかに楽にするものとしてSelf._printChanges()
メソッドがある。これはビューのbody
メソッド内から呼び出すことができる。これを使って、変更されたプロパティの名前をログに記録し、ビューを再レンダリングすることができる。名前のアンダースコアが示すように、このメソッドが出荷するアプリに使うことは想定されていない。
他に、SwiftUIの便利な拡張機能として、FocusState
プロパティラッパーがある。これにより、フォーカスされているかどうかに関係なく、コントロールの状態を管理できる。また、AttributedString
クラスとText
クラスでのマークダウンをサポートし、ガラスのようなぼかし効果をエミュレートすることを目的としたmaterial背景タイプを使えるようになる。このぼかし効果は、背景に表示されるビューで、極薄から極厚まで、さまざまな種類のマテリアルによって生成される。
SwiftUI 3はまだベータ版であり、iOS 15とXcode 13で利用できるようになる。
SwiftUI 3には、ここで説明できる以上のことがたくさんあるので、興味があれば、WWDC 2021のSwiftUIの新機能ビデオをお見逃しなく。