元ネタ
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!
また、一部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の右に余白を開けるにはどうすれば良いかが議論されていましたが、自分であれば次のように書くと思います。
ではでは