Sponsor Link
ボタンのカスタマイズ
ボタンをカスタマイズしようとする時に、大きく2種類のカスタマイズが考えられます。
- ボタンの見た目をカスタマイズする (例:枠をつける)
- ボタンの振る舞いをカスタマイズする (例:押されると回転するボタン)
どちらのカスタマイズも、SwiftUI では、.buttonStyle という modifier を使って行うことができるようになってます。
今回は、見た目のカスタマイズを .buttonStyle を使って行う方法を説明します。
ButtonStyle
ボタンの見た目をカスタマイズしたい時に使う ButtonStyle は、名前そのままですが、ButtonStyle という protocol に準拠したものを作ってカスタマイズします。
Apple のドキュメントは、こちら。
以下は、iOS 上でデフォルトのスタイルと”ほとんど”同じスタイルになるように作ったスタイルです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
struct MyButtonStyle: ButtonStyle { // (1) func makeBody(configuration: Configuration) -> some View { MyButton(configuration:configuration) } // (2) struct MyButton: View { // (2) @Environment(\.isEnabled) var isEnabled let configuration: MyButtonStyle.Configuration var body: some View { // (3) configuration.label // (4) .foregroundColor(isEnabled ? .blue : .gray) // (5) .opacity(configuration.isPressed ? 0.2 : 1.0) } } } |
- makeBody というメソッドを持つことが、ButtonStyle という protocol が要求していることです。ここでは、MyButton という View を返しています。
- ボタンが Enable かどうかの情報は、@Environment から取得して判断に使うことができます。ButtonStyle の中からは参照できないため、独自の View を作りその中から参照しています。
- makeBody の引数 configuration の label に、与えられたラベルの情報が入っています
- Enable かどうかで、フォアグランドカラーを blue と gray で切り替えています
- クリックされているかどうかの情報は、configuration.isPressed に入っていて、その情報によって、透明度(Opacity) を変更しています
このように、状態に応じた色や表示する要素等を指定して作っていくことでボタンの見た目をカスタマイズすることができます。
makeBody が返すのは、View であれば良いので、configuration に含まれる label を使わずに、全く別の View を返すことも可能です。
#”ほとんど”同じと言っているのは、クリックされた時のラベルの色がどのくらい透明(Opacity)になっているかの資料が見つからなかったので、目分量で設定しているためです。
見た目をカスタマイズ
ここまでできれば、あとは、 SwiftUI の コンポーネントや modifier の知識を使うだけです。
角の丸い長方形を背景に持つボタンを作るには、以下のような ButtnStyle を定義して、適用すれば良いです。
- フォアグランド色は、ボタンがEnable であれば .blue、Disable であれば .gray
- バックグラウンドは、角のRが10の長方形
- バックグラウンド色は、ボタンがEnable であれば .red.opacity(0.4)、Disable であれば、.white
- ボタンが押されたら、フォアグランドの opacity を 0.2 にする
上記のようなスタイルを作るには、、以下のようなに定義して、そのスタイルをボタンに .buttonStyle 指定すれば良いことになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
struct MyButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { MyButton(configuration:configuration) } struct MyButton: View { @Environment(\.isEnabled) var isEnabled let configuration: MyButtonStyle.Configuration var body: some View { configuration.label .foregroundColor(isEnabled ? .blue : .gray) .opacity(configuration.isPressed ? 0.2 : 1.0) .padding(15) .background(isEnabled ? Color.red.opacity(0.4) : Color.white) .cornerRadius(10) } } } |
実際に配置すると、以下のような見た目になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
// // ContentView.swift // // Created by : Tomoaki Yagishita on 2020/11/13 // © 2020 SmallDeskSoftware // import SwiftUI struct ContentView: View { @State private var buttonDisabled:Bool = false var body: some View { VStack { Spacer() Button(action: {print("Hello")}, label: { Text("MyButton") }) .buttonStyle(MyButtonStyle()) .disabled(buttonDisabled) .padding() Spacer() Button(action: { buttonDisabled.toggle() }, label: { Text("Toggle Button disable/enable") }) .padding() Spacer() } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } struct MyButtonStyle: ButtonStyle { func makeBody(configuration: Configuration) -> some View { MyButton(configuration:configuration) } struct MyButton: View { @Environment(\.isEnabled) var isEnabled let configuration: MyButtonStyle.Configuration var body: some View { configuration.label .foregroundColor(isEnabled ? .blue : .gray) .opacity(configuration.isPressed ? 0.2 : 1.0) .padding(15) .background(isEnabled ? Color.red.opacity(0.4) : Color.white) .cornerRadius(10) } } } |
まとめ:Button のカスタマイズ方法 (ButtonStyle を使ったカスタマイズ方法)
- ButtonStyle に準拠したスタイルを定義することで、スタイルをカスタマイズできる
- ButtonStyle protocol に準拠するためには、makeBody を実装する必要がある
- makeBody の返す View が、ボタンとして表示される
- makeBody の引数 configuration にラベル等のボタン定義時の情報が渡される
Sponsor Link