🕌

[SwiftUI]ButtonStyleを活用したカスタムButton

2021/06/08に公開

今回はSwiftUIのButtonStyleを使って、ボタンの見た目を変えていきます。
すでに用意されているStyleと、自身で作るカスタムStyleの2種類についてです。

ButtonStyleを使うと何が良いか

こちらでも書きましたが、ButtonStyleを使うと一括でスタイルが適用できるので、サブクラスやViewModifierと比べて大変便利です。

ButtonStyle

https://developer.apple.com/documentation/swiftui/buttonstyle

Buttonの見た目(Style)を変更するためのprotocolです。このButtonStyle protocolに準拠することで、カスタムのStyleを定義することができます。

ButtonStyleの中身を見ていきます。

public protocol ButtonStyle {
    func makeBody(configuration: Self.Configuration) -> some View
    typealias Configuration = ButtonStyleConfiguration
}

public struct ButtonStyleConfiguration {

    public struct Label : View {
        public typealias Body = Never
    }

    public let label: ButtonStyleConfiguration.Label
    public let isPressed: Bool
}

ButtonStyleConfiguration.labelで見た目を変更していけば良いことがわかります。

定義されているButtonStyle(iOS)

iOSでは以下の3つが定義されています。

  • DefaultButtonStyle
  • PlainButtonStyle
  • BorderlessButtonStyle(DefaultButtonStyleと同等)
    どれもシンプルなStyleです。

カスタムButtonStyle

今回は4つカスタムButtonStyleを作成します。

  • RoundedButtonStyle:背景が塗りつぶされた角丸のボタンです
  • CapsuleButtonStyle:背景が塗りつぶされた角が円のボタンです
  • BorderedRoundedButtonStyle:ボーダーをつけた角丸のボタンです
  • BorderedCapsuleButtonStyle:ボーダーをつけた角が円のボタンです

CapsuleButtonStyleの実装を見ていきます。

struct CapsuleButtonStyle: ButtonStyle {
        
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .padding()
            .background(Color.blue)   //背景色
            .foregroundColor(.white)  //文字色
            .font(.body.bold())       //フォントサイズ・スタイル
            .clipShape(Capsule())     //背景の形
            .scaleEffect(configuration.isPressed ? 0.95 : 1)  //ボタンが押された時のエフェクト
            .animation(.easeOut(duration: 0.2)) //エフェクトのアニメーション
    }
}

configuration.labelに対してスタイルを適用しています。
clipShapeを使い、ボタンの形を整えています。

実装結果

定義されているButtonStyle, カスタムのButtonStyleを並べてみました。

上から順に

  • DefaultButtonStyle
  • PlainButtonStyle
  • BorderlessButtonStyle
  • RoundedButtonStyle
  • CapsuleButtonStyle
  • BorderedRoundedButtonStyle
  • BorderedCapsuleButtonStyle

サンプルコード

https://github.com/usk-sample/SwiftUIButtonsSample

Discussion