【Swift UI】ButtonStyleでカスタムデザインボタンの実装方法!
この記事からわかること
- SwiftのButtonとは?
- 構造や書式、使い方
- actionやプロパティ、@State
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:15.0.1
- iOS:17.1
- Swift:5.9
- macOS:Sonoma 14.1
ボタンのスタイルを変更する
Swift UIのButton
構造体のスタイルはbuttonStyle
モディファイアにPrimitiveButtonStyle
プロトコルの任意の値を渡すことで変更することができます。
Button {
} label: {
Text("borderless")
}.buttonStyle(.borderless)
// .buttonStyle(BorderlessButtonStyle()) でも可
PrimitiveButtonStyle型の種類
指定できる値はOSによって異なります。
スタイル名 | 概要 | 対応OS |
---|---|---|
DefaultButtonStyle | 標準のボタンスタイル | iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0 |
PlainButtonStyle | 背景色なし | iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0 |
BorderlessButtonStyle | 背景色なしテキストの下に下線 | iOS 13.0, macOS 10.15, tvOS 17.0, watchOS 8.0 |
BorderedButtonStyle | 背景色があり、角丸の矩形 | iOS 15.0, macOS 10.15, tvOS 13.0, watchOS 7.0 |
BorderedProminentButtonStyle | 背景色があり、角丸の矩形 | iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0 |
LinkButtonStyle | リンク風のボタンスタイル | iOS 14.0+, macOS 11.0+, Mac Catalyst 14.0+ |
CustomButtonStyle | カスタムボタンスタイル | iOS 14.0+, macOS 11.0+, Mac Catalyst 14.0+ |
公式リファレンス:PrimitiveButtonStyle型
実際のデザイン
実際に実装してみると以下のような感じになります。
Button {
} label: {
Text("automatic")
}.buttonStyle(.automatic)
Button {
} label: {
Text("plain")
}.buttonStyle(.plain)
Button {
} label: {
Text("bordered")
}.buttonStyle(.bordered)
Button {
} label: {
Text("borderedProminent")
}.buttonStyle(.borderedProminent)
Button {
} label: {
Text("borderless")
}.buttonStyle(.borderless)
カスタムボタンスタイルを実装する
ButtonStyle
プロトコルに準拠させた構造体を実装することでカスタムボタンスタイルを定義することができます。
/// テーマカラーのボタンスタイル
struct ThemaButtonStyle: ButtonStyle {
// ボタンの活性/非活性状態を取得
@Environment(\.isEnabled) var isEnabled: Bool
func makeBody(configuration: Configuration) -> some View {
configuration.label
.padding(.vertical)
.fontWeight(.bold)
.foregroundStyle(.white)
.background(isEnabled ? .red : .gray)
.clipShape(RoundedRectangle(cornerRadius: 8))
.opacity(configuration.isPressed ? 0.5 : 1) // configuration.isPressedでボタンを押している状態を取得
.animation(.easeOut(duration: 0.2), value: configuration.isPressed)
.shadow(color: .gray,radius: 3, x: 2, y: 2)
}
}
中では@Environment(\.isEnabled)
でボタンの活性状態を取得できます。
@Environment(\.isEnabled) var isEnabled: Bool
ボタンが押されている状態はconfiguration.isPressed
で取得できます。
// configuration.isPressedでボタンを押している状態を取得してUI変更
.opacity(configuration.isPressed ? 0.5 : 1)
使用する際はbuttonStyle
メソッド内でインスタンス化するだけです。
Button {
} label: {
Text("カスタム")
}.buttonStyle(ThemaButtonStyle())
.disabled(flag)
もっとスマートに.buttonStyle(.thema)
のように呼び出したい場合はButtonStyle
をextension
して静的プロパティを追加すれば実装できます。
extension ButtonStyle where Self == ThemaButtonStyle {
static var thema: ThemaButtonStyle {
return ThemaButtonStyle()
}
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。