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

SwiftUI2021

     

TAGS:

⌛️ 2 min.
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 ViewMatery

SwiftUI で開発していくときに、ViewやLayoutのための適切なmodifierを探すのが大変です。
英語での説明になってしまいますが、以下の”SwiftUI Views Mastery Bundle”という本がビジュアル的に確認して探せるので、便利です。

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

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

超便利です

SwiftUIViewsMastery

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

SwiftUI 徹底入門

# SwiftUI は、毎年大きく改善されていますので、少し古くなってしまいましたが、いまでも 定番本です。

Swift学習におすすめの本

詳解Swift

Swift の学習には、詳解 Swift という書籍が、おすすめです。

著者は、Swift の初期から書籍を出していますし、Swift の前に主力言語だった Objective-C という言語についても同様の書籍を出しています。

最新版を購入するのがおすすめです。

現時点では、上記の Swift 5 に対応した第5版が最新版です。

コメントを残す

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