【Swift UI】ButtonStyleでカスタムデザインボタンの実装方法!

【Swift UI】ButtonStyleでカスタムデザインボタンの実装方法!

この記事からわかること

  • SwiftButtonとは?
  • 構造書式使い方
  • actionプロパティ@State

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

ボタンのスタイルを変更する

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型

実際のデザイン

実際に実装してみると以下のような感じになります。

Swift UI】ButtonStyleでカスタムデザインボタンの実装方法!
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)のように呼び出したい場合はButtonStyleextensionして静的プロパティを追加すれば実装できます。

extension ButtonStyle where Self == ThemaButtonStyle {
    static var thema: ThemaButtonStyle {
        return ThemaButtonStyle()
    }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index