SwiftUIのViewModifierについて

初心者向け

の記事。

SwiftUIではViewでUIの要素を指定し、ViewModifierで要素のレイアウトを整えていく。

その書き方はそれぞれの要素に対して


//
//  ContentView.swift
//  Modifier
//
//  Created by kuehar on 2021/07/01.
//

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
            .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

プロジェクトを作ったときはこういう形式でコードが生成されるが、このコードの中の.padding()が実際のViewModifer。

Previewで見てみると最初はこんな感じだが、






例えば.padding(bottom)に変えてみると、


少しだけHello, World!が上に動いている。非常に分かりづらいが。

こういった形で各要素を修飾することによって要素の内容を変えていく。

開発者定義のViewModifier

同時に、開発者側で定義する再利用可能なViewModifierを作成できる。

開発者でどのビューにも適用できる再利用可能なViewModifierを作成したい場合に用いるもので、いくつかのViewModifierを組み合わせて新しいViewModifierを作成することができる、というもの。

例えばApple公式のViewModifierのドキュメントでは以下のようなViewModifierを定義し、使用しています。


//
//  ContentView.swift
//  Modifier
//
//  Created by kuehar on 2021/07/01.
//

import SwiftUI

struct BorderedCaption: ViewModifier {
    func body(content: Content) -> some View {
        content
            .font(.caption2)
            .padding(10)
            .overlay(
                RoundedRectangle(cornerRadius: 15)
                    .stroke(lineWidth: 1)
            )
            .foregroundColor(Color.blue)
    }
}

extension View {
    func borderedCaption() -> some View {
        modifier(BorderedCaption())
    }
}

struct ContentView: View {
    var body: some View {
        Image(systemName: "bus")
            .resizable()
            .frame(width:50, height:50)
        Text("Downtown Bus")
            .borderedCaption()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Simulatorではこのようになる。


チームで開発する場合はコードの再利用で工程を削減できそうな反面、ある程度のルールを持って運用しないと可読性が低くなりそうで難しそう。

コメント

このブログの人気の投稿

Braveブラウザの同期機能をiPhoneで設定した話。

failed: unable to get local issuer certificate (_ssl.c:1123)と出たので解決した話

自作のChrome Extensionをインポートした時に "Invalid value for 'content_scripts[0].matches[0]': Empty path."というエラーが出たので解決した