【SwiftUI】iOS16+のGauge|ゲージビューの作り方

iOS16+から、SwiftUIの新しいビュー機能「Gauge」が追加されました!

Gaugeを用いることで、「ある範囲内の値」をゲージスタイルで表現できます。

複数のスタイルが用意されているほか、独自のゲージレイアウトを作ることも可能です。

👉ドキュメント: Gauge | Apple Developer Documentation

本記事では、Gaugeの各機能と使い方について見ていきます。

[ 本記事はこんな人におすすめ ]

・ゲージスタイルのビューを実装したい

・SwiftUIでアプリ開発をしている

Gaugeの基本

最もシンプルなGaugeのコード

Gaugeビューの最もシンプルな実装コードは以下です。

・Gaugeの引数「value:」にDouble型の値を渡すことで、ゲージの現在値を表現します。範囲指定が無い場合、値の幅は0.0〜1.0です。

・Gaugeのクロージャ内では、ゲージの説明ラベルを設定できます。

				
					/// ゲージ量の現在値
@State private var current = 0.4

Gauge(value: current) {
    Text("<ゲージの説明>")
}
				
			

ゲージ値の幅を設定する

Gaugeの引数in:に最小値・最大値を渡すことで、ゲージ値の幅を設定できます。

開始値と終了値をラベル表示する

ゲージに「開始値」「現在値」「終了値」を表すラベルを追加することができます。

Gaugeが持つ複数のトレイリングクロージャを使用することで、ラベルを追加します。

以下は、ドキュメントに記載されている実装コードです。

				
					/// ゲージの現在値+範囲を追加する
@State private var currentValue = 67.0
@State private var minValue = 0.0
@State private var maxValue = 170.0

/// Gaugeに値の範囲を渡す
Gauge(value: currentValue, in: minValue...maxValue) {
    Text("BPM")
} currentValueLabel: {
    Text("\(Int(currentValue))")
} minimumValueLabel: {
    Text("\(Int(minValue))")
} maximumValueLabel: {
    Text("\(Int(maxValue))")
}
				
			

ゲージのスタイルを変更する(GaugeStyle)

ゲージのスタイルを変更するには、ビュー修飾子.gaugeStyleを使用します。

例えば初期化子に.accessoryCircularを渡すことで、ゲージが円形スタイルに変化します。

				
					Gauge(value: currentValue, in: minValue...maxValue) {
    // ...
}
.gaugeStyle(.accessoryCircular) // 👈スタイルを変更
				
			

その他、複数のゲージスタイルが用意されています。各スタイルの外観を以下に挙げます。

スタイルの指定が無い場合、デフォルトでは.linerCapacityが適用されているようです。

.linerCapacity

.accessoryLiner

.accessoryLinerCapacity

.accessoryCircular

.accessoryCircularCapacity

ゲージのカラーを変更する

・ラベルのカラー変更(foregroundColor)

ゲージ内のラベル色を変更したい場合、各ラベルの要素に対してカラー指定をします。

・ゲージ本体のカラー変更(tint)

ゲージ本体のカラーを変更する場合、Gaugeにビュー修飾子.tintを渡して、システムカラーを指定します。

ラベルのカラー変更と違い、.foregroundColorによる色指定だとカラーが変更されないので注意してください。

以下のように、Gradientなどによってカラフルなグラデーションを付与することもできます。

ゲージのサイズ変更について

フレーム指定による外観(サイズ)の変化

ゲージは.frameのフレーム指定によって外観サイズが変化する場合がありますが、スタイルごとに一定の制限があります。

ライン型、サークル型、それぞれのスタイルを見ていきます。

・ライン型スタイルのフレーム指定

ライン型スタイルのゲージビューは、width(横)のフレーム指定がゲージの外観にも反映されます。

height(縦)のフレーム指定では、ビューのフレーム領域が変化するのみで、ゲージ本体の外観は変化しません。

・サークル型スタイルのフレーム指定

サークル型スタイルのゲージは、width(横)、height(縦)、どちらのフレーム指定であってもゲージ本体のサイズは変化しません。

サークル型ゲージ本体のサイズを変更するには、後述の.scaleEffectモディファイアを使用します。

scaleEffectによるサイズ変更

.scaleEffectモディファイアを使えば、出力されたビューの外観を拡大・縮小できます。これによって、ゲージの表示サイズを変更することが可能です。

⚠️scaleEffectの注意点

注意点として、.scaleEffectによる拡大・縮小は、「ビューが持っているフレーム領域には反映されない」ということに気をつけてください。

以下のコードでは、同じレイアウト構成のサークル型ゲージに、.scaleEffectを追加して表示を拡大させています。

ゲージのビュー表示は拡大されて大きくなっていますが、ビューそれぞれが持つフレーム領域(赤枠)は変化していないことがわかります。

つまり、「サイズが大きくなった分のスペース間隔を、隣り合うビュー同士が取らない」ということです。

ビュー領域は変化しないため、隣のビューと重なっている

ビュー同士の干渉を避けるために、拡大サイズ分の領域をあらかじめ.frameで確保しておくなどで対応しましょう。

カスタムゲージスタイルの作成

Gaugeにはあらかじめ複数のスタイルが用意されていますが、独自のカスタムゲージスタイルを自作することも可能です。

独自のGaugeStyleの準備

ゲージスタイルは、以下の手順で自作することができます。

1. GaugeSytleプロトコルに準拠した構造体(struct)を作成

2. 構造体の中にmakeBody(configuration:)メソッドを定義

				
					/// カスタムゲージスタイルの作成
/// GaugeStyleプロトコルに準拠させる
/// makebody(configuration:)メソッドの中でゲージの外観を作る
struct CustomGaugeStyle: GaugeStyle {

    func makeBody(configuration: Configuration) -> some View {

        // <ここでゲージの外観を構築する>

    }
}
				
			

makeBody(configuration:)メソッド内で構築したビューが、そのままゲージの外観として出力されます。

引数「Configuration」について

makeBodyメソッドの引数Configurationには、Veiw側のGaugeに渡した各データが渡ってきます。

主に以下のデータをGaugeビュー側から取得できます。

・label

・value

・currentValueLavel

・minimumValueLavel

・maximumValueLavel

例えば、Gaugeビューのラベルに「Text(“CodeCandy”)」を渡した場合、makeBody内にてconfiguration.labelとすることで、「Text(“CodeCandy”)」を取得できます。

				
					struct CustomGaugeView: View {

    @State private var value = 50.0

    var body: some View {

        Gauge(value: value) {
            Text("CodeCandy") // label
        }
        .gaugeStyle(CustomGaugeStyle())
    }
}

// View側でGaugeに渡した値は、引数「configuration」に渡ってくる
struct CustomGaugeStyle: GaugeStyle {

    func makeBody(configuration: Configuration) -> some View {

            configuration.label // Text("CodeCandy")
    }
}
				
			

このように、Gaugeビューから渡ってきた値を用いて、カスタムゲージのレイアウトを構築していきます。

レイアウトを構築する

では、実際にカスタムゲージのレイアウトを作ってみましょう。

makeBody(configuration:)メソッドの中でカスタムゲージのビューレイアウトを構築していきます。

ここでは一例として、「現在のレベルと経験値を表現したカスタムゲージレイアウト」を作成しました。

レイアウトの実装コードは以下です。

				
					/// カスタムゲージスタイルの作成
struct LevelGaugeStyle: GaugeStyle {

    let gradient = LinearGradient(colors: [.orange, .red], startPoint: .leading, endPoint: .trailing)

    func makeBody(configuration: Configuration) -> some View {
        ZStack {

            Circle()
                .foregroundColor(Color(.systemGray6))

            Circle()
                .trim(from: 0, to: 0.75 * configuration.value)
                .stroke(gradient, lineWidth: 20)
                .rotationEffect(.degrees(135))

            Circle()
                .trim(from: 0, to: 0.75)
                .stroke(Color.black, style: StrokeStyle(lineWidth: 10,
                                                        lineCap: .butt,
                                                        dash: [1, 34]))
                .rotationEffect(.degrees(135))

            VStack {
                Text("Level")
                    .font(.title)
                    .bold()
                    .foregroundColor(.gray)

                configuration.label
                    .font(.system(size: 80, weight: .bold, design: .rounded))
                    .foregroundColor(.gray)
            }

        }
        .frame(width: 300, height: 300)
    }
}
				
			

あとは作成したカスタムゲージスタイルをGaugeに設定してあげればOKです。

まとめ

以上、iOS16+におけるSwiftUIのビュー機能「Gauge」についてでした!

要点をまとめておきます。

ある範囲の値をゲージ型のレイアウトで表現する

・ラベルカラーは「foregroundColor」、ゲージ本体のカラーは「tint」で編集する

・サイズ調整は「frame」または「scaleEffect」を使う(ビュー領域に注意)

・独自のゲージスタイルを作成可能

使い方次第で、様々な画面レイアウトに活用することができそうですね!

ただ、デフォルトのスタイルだけだとレイアウトの操作に少々制限があるので、カスタムゲージスタイルも使いこなすことができれば、より柔軟性があって良いかと思います。

本記事が参考になりましたら幸いです。

本記事のソースコード

本記事で使用しているサンプルコードはGitHubにて公開されています。

コード内容の確認にぜひご利用ください🍎

ソースコードを見る>>

\  SHARE  /

Twitter
Facebook
Email

✏️ アプリ開発が学べる勉強会を開催中! 

CodeCandyではアプリ開発を学ぶための勉強会を定期開催しています。
学習する習慣を身につけたい、他の参加者と作業したい、アプリ開発の基本をマスターしたい、という方のために無料で学べる勉強会です。
グループにメンバー登録して頂くと、イベント開催時にメールで通知されます。

▶️グループのメンバーとして参加する

徹底した基礎学習からマスターするiPhoneアプリ開発集中オンライン講座開講!

本書「iPhoneアプリ開発集中講座」を執筆している現役エンジニア講師陣が直接に指導!
基礎、課題実習で実践力を鍛えて、オリジナルアプリ公開までチャレンジ!
充実した転職支援もあるので、エンジニアへ転職したい人にもおすすめです!

まずは、現役エンジニアに相談できる無料相談をご利用ください。

\ Official /

By 中川 賢亮

2022年2月よりSwift学習を始め、4月からiOSアプリ開発オンラインスクール「CodeCandy」にてアプリ開発を学ぶ。 2023年10月に個人開発アプリ「unico」をリリース。現在はアプリの機能アップデートをしながら、スクール運営の技術ブログの執筆や、出版書籍の入稿チェック・デバッグにも携わる。