ダウンロード サンプルファイル (149.5 KB)
より高度な表現が可能となった──Graphics and Layout
プログラムでの処理の向上のほかに、UIの外観や表示形式についても機能が充実しました。主要な変更点について、Shape Style/Layoutの2つでまとめられています。
| ジャンル | 概要 |
|---|---|
| Shape Style | UIの外観 |
| Layout | 画面レイアウト |
それぞれの項目について簡単なサンプルコードとともに紹介します。
Shape Style
UIの前景スタイル(foregroundStyle)と背景スタイル(backgroundStyle)を指定できるようになりました。前景スタイルには色や影などの装飾、背景スタイルには背景として画像/色/グラデーションなどを指定することができます。
struct ContentView: View {
var body: some View {
Image(systemName: "swift")
.frame(width: 150,height: 150)
.background(in: Circle())
.foregroundStyle(.white.shadow(.drop(color:.black, radius:2, x:4, y:4))) // -------- ①
.backgroundStyle(.orange.gradient) // -------- ②
.font(.system(size:60))
}
}
最初にSwiftのアイコン画像を円の形状で用意します。ここにforegroundStyleメソッドでアイコンの色を白、黒い影をつけます(①)。影をつけるときには、色/影のエフェクト/オフセットを指定することができます。その後にbackgroundStyleメソッドで、オレンジのグラデーションで背景色をつけます。サンプルのようにロゴ画像のような外観を簡単に実現できるようになりました。
Layout
動的にレイアウトを変更するAnyLayoutとグリッド表示を行うGridという新しい仕様が追加されました。具体的なサンプルをあげて説明します。
AnyLayout
AnyLayoutはレイアウトを動的に変更できるプロトコルです。画面上に配置済みのビューを破棄することなどはなく、動的にレイアウトを変更できます。AnyLayoutを利用してレイアウトを動的に変更するサンプルは次のとおりです。
struct ContentView: View {
// レイアウトを切り替えるフラグ
@State var isChangeLayout: Bool = false
// 前節のサンプルで作成したImage
let image: some View = Image(systemName: "swift")
.frame(width: 150,height: 150).font(.system(size:60))
.background(in: Circle()).backgroundStyle(.orange.gradient)
.foregroundStyle(.white.shadow(.drop(color:.black, radius:2, y:4)))
var body: some View {
VStack {
// 動的に変更するレイアウトを定義
let layout: AnyLayout = isChangeLayout ? AnyLayout(HStackLayout()) : AnyLayout(VStackLayout()) // -------- ①
// Imageを2つ並べてタップでレイアウトを変更
layout {
image
image
}
.padding()
.animation(.spring(), value: isChangeLayout)
.onTapGesture { // --------②
isChangeLayout.toggle()
}
}
}
}
バインディング変数isChangeLayoutの値によって水平方向または垂直方向のAnyLayoutを定義します。AnyLayoutの定義には、条件付きの水平方向レイアアウトを定義するHStackLayout構造体、条件付きの垂直方向レイアアウトを定義するVStackLayout構造体を利用します。プレビュー画面とともに利用するHStack/VStackの構造体ではないことに気を付けてください。onTapGestureメソッドで、タップ時にisChangeLayoutの値を切り替わり、レイアウトもアニメーションを伴って切り替わります(②)。
Grid
Gridは、グリッドの形式で表示を行う構造体です。Gridブロック内にGridRow構造体を配置することで、行単位での表示を指定することができます。Gridを使った簡単なサンプルは次のとおりです。
struct SquareView: View { // グリッドのセルに表示するビューを定義
let color: Color
var body: some View {
color.frame(width: 50, height: 50)
}
}
struct ContentView: View {
var body: some View {
Grid { // -------- ①
// 赤5セルを表示
GridRow { // --------②
ForEach(0..<5) { _ in
SquareView(color: .red)
}
}
// 青3セルを空白を挟んで表示
GridRow { // --------②
SquareView(color: .blue)
Color.clear.gridCellUnsizedAxes([.horizontal, .vertical]) // --------③
SquareView(color: .blue)
Color.clear.gridCellUnsizedAxes([.horizontal, .vertical]) // --------③
SquareView(color: .blue)
}
// 緑3セルを中央に詰めて表示
GridRow { // --------②
Color.clear.gridCellUnsizedAxes([.horizontal, .vertical]) // --------③
ForEach(0..<3) { _ in
SquareView(color: .green)
}
Color.clear.gridCellUnsizedAxes([.horizontal, .vertical]) // --------③
}
}
}
}
グリッドは、Gridブロック(①)の中にGridRowブロックを行を設ける(②)ことで表示できます。グリッドのセルを空けたい場合は、色やビューで必要なスペースを埋めるgridCellUnsizedAxesメソッドを利用します(③)。
またGridブロックは、一定の領域を確実に表示するという性質を利用して、表を作成するという使い方もできます。連載第1回で紹介した複数のリストをまとめるTableはiOSには未対応です。Gridをうまく使うと、iOSでも複数のリストをまとめて表示することができます。Gridを利用して、月当たりの売り上げデータを表にするサンプルは次のようになります。
struct ContentView: View {
var body: some View {
Grid(alignment: .leading, horizontalSpacing: 0, verticalSpacing: 10) { // -------- ①
ForEach(MonthAmount.examples) { item in
GridRow(alignment: .firstTextBaseline) { // -------- ②
Text(item.month)
Text("\(item.amount)")
}.padding([.leading, .trailing])
GridRow {
Rectangle().frame(height: 1).gridCellColumns(2) // -------- ③
}
}
}
}
}
Grid構造体自体には、セルを揃える基準/水平方向のスペース/垂直方向のスペースを指定することができます(①)。Gridブロックの中で、月当たりの売り上げデータをForEachでループします。最初に月名と売り上げを表示します(②)。その後に、高さを1として矩形をグリッドのセルを統合するgridCellColumnsメソッドで2セル分配置します(③)。ループが終わると、月当たりの売り上げデータが表で表示されます。
まとめ
今回は「What's new in SwiftUI」の後半部分で紹介されたSwiftUI 4の新しい機能について説明しました。次回からSwiftUI 4の機能を使ったもう少し実用的なサンプルを作成していきます。
参考資料
この記事は参考になりましたか?
既に会員の方はを行ってください。
- この記事の著者
-
WINGSプロジェクト 片渕 彼富(カタフチ カノトミ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 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本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
