[SwiftUI] Text の LineHeight をデザインに合わせたら余分なスペースができて困った話
デザインの Text 表示について
普段アプリデザインを相談する際に Figma を利用しているが、
Figma で Text を書くと LineHeight が加わっていることが多い。
上の例は1行の Text が2つ縦に並んでいる。
Text のサイズは 16px、LineHeight が 24px になっている。
そのため Text のサイズに加えて、8px 分の余白が上下に入っていることが分かる。
もちろん Figma で LineHeight を Text のサイズと合わせることもできるが、
今回はデザインオーダーとして LineHeight を考慮した Text の実装を行う。
SwiftUI の Text に LineHeight を追加する
1行の Text に LineHeight を追加する方法はこちらを参考にした。
独自の ViewModifier を実装し Text に適用することで実現できるとのこと。
struct ContentView: View {
VStack {
Text("もじ文字モジ")
.modifier(TextModifier()) // Text サイズと LineHeight を適用
Text("もじ文字モジ")
.modifier(TextModifier())
}
}
struct TextModifier: ViewModifier {
func body(content: Content) -> some View {
content
.font(.system(size: 16))
.lineSpacing(lineHeight - font.lineHeight)
.padding(.vertical, (lineHeight - font.lineHeight) / 2)
}
}
lineHeight - font.lineHeight
の部分は、LineHeight と Text の高さ(サイズ)との差になるため、上の例で言うと 24px - 16px = 8px
となる。
Modifier適用前後の比較は以下の通り。
Modifier適用前 | Modifier適用後 |
---|---|
とりあえず LineHeight は加わっていそう。
困ったこと
LineHeight が加わったので安心していたのだが、デザインと見比べてみると...
デザイン | Modifier適用後 |
---|---|
余白が多い!🤔
デザイン通りに LineHeight を適用したはずが、全然違う結果になってしまった。
原因
Xcode で Preview を見てみると、
Text と Text の間にスペースができている!
SwiftUIでは View の余白は Margin ではなく全て Padding で行うため、どうやら Text の Padding ではなさそう...
解決方法
色々調べてみるとこちらの方法で解決することがわかった。
struct ContentView: View {
VStack(spacing: 0) { // <--- ここを変更
Text("もじ文字モジ")
.modifier(TextModifier()) // Text サイズと LineHeight を適用
Text("もじ文字モジ")
.modifier(TextModifier())
}
}
struct TextModifier: ViewModifier {
// ~~~ 略 ~~~
}
今度はどうやら VStack に原因があるようで、 spacing: 0
を書かないと今回のように View 間でスペースができてしまうらしい...
スペースが邪魔なので、VStackを修正してみる。
デザイン | VStack修正後 |
---|---|
デザインの LineHeight と一致しているように見える!(わかりにくい)
ということで、Text に LineHeight を適用するときは注意したほうが良さそうという話でした。
あと毎回 VStack に spacing: 0
をつけるのは面倒なので、何か良い方法があれば教えてください...
Author And Source
この問題について([SwiftUI] Text の LineHeight をデザインに合わせたら余分なスペースができて困った話), 我々は、より多くの情報をここで見つけました https://zenn.dev/satoryo56/articles/0eb589a918bbb1著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol