[SwiftUI] ButtonStyle による Button カスタマイズ

SwiftUI2021

SwiftUI2021 で ButtonStyle を使った Button の見た目カスタマイズを説明します。

環境&対象

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

  • macOS Monterey 12.1 beta3
  • Xcode 13.2 beta2
  • iOS 15

ButtonStyle による Button のカスタマイズ

SwiftUI2020 での ButtonStyle でのカスタマイズは、以下で説明しました。
SwiftUI[SwiftUI] Button の見た目カスタマイズ ButtonStyle の使い方

SwiftUI2021 では、Button に role という属性も追加されたので、改めて、ButtonStyle を使ったカスタマイズを説明していきます。

ButtonStyle

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

他に、PrimitiveButtonStyle という protocol も用意されていて こちらは、動作をカスタマイズする時に使う用です。

makeBody(configuration:)

ButtonStyle という protocol を満たすには、このメソッドを実装することが必要になります。

引数の Configuration は、ButtonStyle では、ButtonStyleConfiguration が渡されてきます。

ButtonStyleConfiguration

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

label, isPressed, role という3つの情報を持っています。

  • label は、Button のうちの label 情報
  • isPressed は、ボタン押下されているかの情報
  • role は、role として指定された情報

MyButtonStyle を作ってみる

新しく導入された role 情報に応じて表示を変える ButtonStyle を作ってみます。

3種類の role 設定されたビュー

以下のコードをベースに作ってみます。3種類の role を指定したボタンを並べています。


import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Button(action: {},
                   label: {Text("role: none")})
            Button(role: ButtonRole.cancel, action: {},
                   label: {Text("role: cancel")})
            Button(role: .destructive, action: {},
                   label: {Text("role: destructive")})
        }
            .padding()
    }
}
defaultStyle

それぞれに、デフォルトのスタイルが適用されているため、.destructive の role が指定されたボタンは、テキストが赤く表示されています。

MyButtonStyle

role に応じて、以下のようになる ButtonStyle を作ってみます。

  • .destructive 指定で、テキストが緑になる
  • .cancel 指定されているとテキストの透明度が 0.5 になる

configuration に保持されている label へ、該当する View Modifier を設定していくことになります。


struct MyButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            // (1)
            .opacity(configuration.role == .cancel ? 0.5 : 1.0)
            // (1)
            .foregroundColor(configuration.role == .destructive ? .green : .black)
    }
}
コード解説
  1. configuration が保持する role が .cancel であれば、透明度を 0.5 にしています
  2. configuration が保持する role が .destructive である時に、foreground color を green にしています
MEMO
デフォルトの Style を上書きしているので、ボタンを押された時にリアクションするためには、isPressed を使って、色を変える等の修飾が 別途 必要となります

MyButtonStyle を適用する

ButtonStyle に準拠する形でつくった MyButtonStyle を適用するには、他の ButtonStyle と同様に、.buttonStyle で指定するだけです。


import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Button(action: {},
                   label: {Text("role: none")})
            Button(role: ButtonRole.cancel, action: {},
                   label: {Text("role: cancel")})
            Button(role: .destructive, action: {},
                   label: {Text("role: destructive")})
        }
        // (1) : .buttonStyle で指定する
        .buttonStyle(MyButtonStyle())
            .padding()
    }
}
MyButtonStyle

まとめ:ButtonStyle による Button カスタマイズ

role に指定された情報を使って修飾を変更する ButtonStyle を作ってみました

ButtonStyle による Button カスタマイズ
  • ButtonStyle に準拠したスタイルを定義することで、スタイルをカスタマイズできる
  • ButtonStyle protocol に準拠するためには、makeBody を実装する必要がある
  • makeBody の返す View が、ボタンとして表示される
  • ButtonStyleConfiguration が configuration として渡されるので、その情報を使って、label を修飾する

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

SwiftUI 学習におすすめの本

SwiftUI 徹底入門

SwiftUI は、グラフィカルなライブラリということもあり、文字だけのテキストよりは、画像が多く入れられた書籍を読むと理解が進みやすいです。

自分で購入した中でおすすめできるものとしては、以下のものです。

2019 年発表の SwiftUI 1.0 相当を対象にしているので、2020/2021 に追加された一部の機能は、説明されていません。

ですが、SwiftUI 入門書としては、非常によくできていますし、わかりやすいです。 この本で学習した後に、追加分を学習しても良いと思います。

SwiftUIViewsMastery

英語での説明になってしまいますが、以下の本もおすすめです。

1ページに、コードと画面が並んでいるので、非常にわかりやすいです。

View に適用できる modifier もわかりやすく説明されているので、ビューの理解だけではなく、どのような装飾ができるかも簡単にわかります。

超便利です

SwiftUIViewsMastery

販売元のページは、こちらです。

コメントを残す

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