【SwiftUI】modifier(モディファイア)の自作方法!カスタムモディファイア

この記事からわかること

  • SwiftUImodifier(モディファイア)とは?
  • モディファイアを自作する方法
  • カスタムモディファイアとは?
  • ViewModifierプロトコルとは?
  • 通常のモディファイアのように呼び出す方法
  • 引数を持たせる方法

index

[open]

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

みんなの誕生日

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

posted withアプリーチ

SwiftUIでTextやVStackなどのView構造体を変化させるために使用するmodifier(モディファイア)を自作する方法をまとめました。

modifierメソッドとは?

fontpaddingなど数あるモディファイアですが、大元となっているのはViewプロトコルに定義されているmodifierメソッドです。SwiftUIではこのメソッドを拡張してさまざまなモディファイアが定義されています。

protocol View {
  var body: Self.Body

  func modifier<T>(_ modifier: T) -> ModifiedContent<Self, T>
}

この状態を理解した上でカスタムモディファイアの作成に移っていきたいと思います。

modifier(モディファイア)を自作する方法

流れ

  1. ViewModifierに準拠した構造体を作成
  2. modifierメソッドで呼び出す

モディファイアを自作するには構造体の作成が必要になります。この構造体にカスタムのモディファイアを作っていくのですが、0から作るというよりも既存のモディファイアをあらかじめ組み合わせて置いて再利用しやすいように作るのが目的になります。

また作成の手順は公式リファレンスにも掲載されているのでそちらも参考にしてください。

ViewModifierに準拠した構造体を作成

まずはViewModifierプロトコルに準拠させた構造体を定義します。準拠させるためにはbodyメソッドの定義が必要になります。その引数から実際にモディファイアを適応させるContentが受け取れるので、Contentに対して以下のようにモディファイアを列挙していきます。

struct BlackBackCyanText: ViewModifier {
    func body(content: Content) -> some View {
        content
            .font(.title)
            .padding(10)
            .foregroundColor(.cyan)
            .background(.black)
            .cornerRadius(5)
    }
}

これでカスタムモディファイアの定義が完了しました。続いてこれを実際にText構造体などに使用する方法をみていきます。

modifierメソッドで呼び出す

カスタムモディファイアを適応させるにはmodifierメソッドの引数にカスタムモディファイアをインスタンス化するだけです。

struct ContentView: View {
    var body: some View {
        VStack{
            Text("Hello")
                .modifier(BlackBackCyanText())
            Text("World")
                .modifier(BlackBackCyanText())
        }
    }
}

カスタムモディファイアを使用することで上記のように複数のビューに対して同じデザインを簡単に使い回すことが可能になります。

しかしこれではまだmodifierメソッドを呼び出すのが冗長的です。これをpaddingなどと同じような形で呼び出すようにしていきたいと思います。

modifierメソッドを使わずに通常のように呼び出す

以下のような形で呼び出せるようにするにはViewを拡張していきます

struct ContentView: View {
    
    var body: some View {
        VStack{
            Text("Hello")
                .blackBackCyanText()
            Text("World")
                .blackBackCyanText()
        }
    }
}

以下のようにViewを拡張して中に新しくメソッドを増やしていきます。このメソッド名が実際にモディファイアとして付与することになる修飾名になります。

extension View {
    func blackBackCyanText() -> some View {
        modifier(BlackBackCyanText())
    }
}

引数を持たせる

カスタムモディファイアでは引数を持たせることも可能です。これによりカラーだけを変えたり、サイズだけを変えると言った使い回しがしやすくなります。引数を持たせるには定義したViewModifier構造体にプロパティを持たせます

 // MARK: - 丸型背景色
struct BackRoundColor: ViewModifier {
    let backgroundColor: Color
    func body(content: Content) -> some View {
        content
            .frame(width: 40, height:40)
                .background(backgroundColor)
                .foregroundColor(.white)
                .cornerRadius(50)
                .compositingGroup()
                .shadow(color: .gray,radius: 3, x: 2, y: 2)   
    }
}

extension View {
    func BackRoundColor(color:Color) -> some View {
        modifier(プロジェクト名.BackRoundColor(backgroundColor: color))
    }
}

Imageなど限定のモディファイアを含んだカスタムモディファイアの作り方

Image構造体の持つresizableなど、特定のViewしか持たないモディファイアを含んだカスタムモディファイアを定義したい場合は上記の方法ではなく、そのViewを拡張(extension)してカスタムモディファイアを定義します。

extension Image {
    
    func ex_ResizableTopIconModifier() -> some View {
        self
            .resizable(resizingMode: .stretch)
            .frame(width: 200, height: 150)
            .padding(.bottom,145)
            .foregroundColor(Color.white)
    }
}

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

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

私がSwift UI学習に使用した参考書

searchbox

スポンサー

ProFile

ame

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

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

New Article

index