40
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SwiftUIの可読性を上げるために

Last updated at Posted at 2022-07-12

元ネタ

SwiftUIの課題点

SwiftUIでは、同じ見た目をあらゆる記述で表現することができます。
故に可読性はエンジニアの腕の見せ所でもあります。
ここでは、SwiftUIのコンポーネントを参考に可読性の上げ方を考えてみます。

コンポーネントを構成する要素を考える

可読性を上げる上でヒントになるのがLabelクラスです。

Label(title: {
  Text("name")
},icon: {
  Image("image")
})

このクラスは、TextとImageで構成されています。
一見すると、このLabelクラスは次のように書き換えられると思えます。

HStack {
    Text("name")
    Image("image")
}

しかし、このようにHStackでまとめるとHStack内の関係性が分かりにくくなります。
例えば、次のコードはImageとTextの関係性が不明瞭です。

HStack {
  Image("favorite-image")
  Image("user-image")
  Text("username")
}

Labelという名前を付けることでこの組み合わせが同一の要素を示していることが明確になりました。

HStack {
  Image("favorite-image")
  Label(icon: "user-image", text: "username")
}

このように、SwiftUIでは要素の塊に名前を付けて一つの上位APIコンポーネントとして表現します。(アトミックデザインを想像すると分かりやすいです)
類似のコンポーネントでは、ScrollViewとGridを合わせたListやTable、Textとタップ処理を組み合わせたButtonなどがあります。
これらのAPIをなるべく利用することで、コードの可読性を上げ、またSwiftUIの標準的な挙動に沿ったアプリを作ることができます。

上位APIを使うメリット・デメリット

上位APIは、挙動や見た目の選択肢が絞られるという制約があります。
例えば、List内にボタンを配置した場合その大きさに関わらずタップのハイライトがセル全体にかかります。
このような挙動を回避するには、より下位のAPIやUIViewの埋め込みを利用する必要があります。
この制約を緩和するために、上位のAPIにはStyleと呼ばれる機構が用意されています。
Styleを選択することで、ある程度の見た目の選択肢を得ることができます。

Picker("Server", selection: .constant(1)) {
  Text("Production")
  Text("Development")
  Text("Local")
}.pickerStyle(.segmented) //style!

CleanShot 2022-07-12 at 23.33.16@2x.png

CleanShot 2022-07-12 at 23.33.24@2x.png

また、一部Styleでは自作のStyleを作ることもできます。

extension LabelStyle where Self == MonsterCellLabelStyle {
    static var monster: MonsterCellLabelStyle {
        MonsterCellLabelStyle()
    }
}

struct MonsterCellLabelStyle: LabelStyle {
    func makeBody(configuration: Configuration) -> some View {
        HStack(spacing: 32) {
            configuration.icon
                .scaledToFit()
                .frame(width: 68, height: 68)
            configuration.title
                .font(.title)
        }
    }
}

これらを駆使することで、意味のない構造定義を減らし、より意図の伝わるコードを書くことができます。
自作の上位APIを作る際も、styleを生やせる単位で切り分けているのかを意識すると良いかもしれませんね。

おまけ:Spacerを使う違和感の正体

より具体的な例として、次のようなSpacerの使い方になんとなく違和感を覚えることがあると思います。

HStack {
  HStack {
    Image()
    Text()
  }
  Spacer()
}

これは明らかにSpacerを使うために使われたHStackが認知負荷を高めているためです。
一方でほとんどの人は次のようなコードでは気にならないはずです。

HStack {
  Text()
  Spacer()
}

上位APIの存在は、最初のコードを次のように理解させてくれます。

HStack {
  Label()
  Spacer()
}

可読性が上がったことが分かるかと思います。

元ネタ別解

元ネタでは、Textの右に余白を開けるにはどうすれば良いかが議論されていましたが、自分であれば次のように書くと思います。

CleanShot 2022-07-12 at 23.50.39@2x.png

ではでは

40
18
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?